]> git.corax.cc Git - toolbox/log
toolbox
3 years agoinclude/ipc: Add "topic" field to pubsub IPC messages
Matthias Kruk [Sat, 17 Sep 2022 05:22:07 +0000 (14:22 +0900)]
include/ipc: Add "topic" field to pubsub IPC messages

Messages that were sent with ipc_endpoint_publish() don't contain
information about the topic that they were published on, making it
impossible for the receiver to determine what topic a message was
published on if they are subscribed to more than one topic.

This commit adds a new field "topic" to IPC messages and modifies
ipc_endpoint_publish() so that it sets the field appropriately. This
further adds the function ipc_msg_get_topic() that may be used to
determine the topic an IPC message was published on.

3 years agotest/ipc: Fix comparisons in test cases for ipc_endpoint_recv()
Matthias Kruk [Sat, 17 Sep 2022 05:17:38 +0000 (14:17 +0900)]
test/ipc: Fix comparisons in test cases for ipc_endpoint_recv()

In the test cases for ipc_endpoint_recv(), the comparisons used to
check the correctness of the received data are inverted, causing the
tests to fail when they should succeed and vice-versa.

This commit inverts the incorrect conditions.

3 years agotest/ipc: Fix return values in test case for ipc_endpoint_open()
Matthias Kruk [Sat, 17 Sep 2022 05:17:01 +0000 (14:17 +0900)]
test/ipc: Fix return values in test case for ipc_endpoint_open()

When testing whether ipc_endpoint_open() correctly opens a private
endpoint, the return values of the test case are inverted, causing
the test to fail when it should succeed and vice-versa.

This commit inverts the return values of the test case.

3 years agotest/ipc: Make setup() function idempotent
Matthias Kruk [Sat, 17 Sep 2022 05:16:24 +0000 (14:16 +0900)]
test/ipc: Make setup() function idempotent

The setup() function in the test spec for the ipc module is not
idempotent, causing the second and all subsequent test cases that
use it to fail.

This commit modifies the setup() function so that it does not fail
if it is called more than once.

3 years agotest/ipc: Fix typo in test case for ipc_endpoint_send()
Matthias Kruk [Sat, 17 Sep 2022 05:14:27 +0000 (14:14 +0900)]
test/ipc: Fix typo in test case for ipc_endpoint_send()

The test case that checks if ipc_endpoint_send() can send messages
to private endpoints contains a typo, causing the test case to fail.

This commit fixes the typo in the test case.

3 years agoinclude/opt: Add a default regex and action
Matthias Kruk [Thu, 11 Aug 2022 18:21:40 +0000 (03:21 +0900)]
include/opt: Add a default regex and action

The regex and action of an option may be unset, making it necessary
to check their value before using them.

This commit modifies the opt module to define a default regex and
action in case the user didn't provide one, allowing the parser to
omit checks if the two are unset.

3 years agoinclude/opt: Initialize value of options that don't have a value
Matthias Kruk [Thu, 11 Aug 2022 18:14:19 +0000 (03:14 +0900)]
include/opt: Initialize value of options that don't have a value

The opt module uses the value of options that aren't followed by a
parameter to count how often the option was on the command line.
However, in this case it never initializes the value.

This commit modifies the opt module so that it initializes the
value of options that are not followed by a parameter to 0.

3 years agoinclude/opt: Remove summary of short options from help text
Matthias Kruk [Thu, 11 Aug 2022 18:04:19 +0000 (03:04 +0900)]
include/opt: Remove summary of short options from help text

The help text displayed by the opt module contains a summary of all
short options in the title. However, a cursory search showed that
most commandline tools don't do that. Thus, this "feature" may be
removed.

This commit removes the summary of short options from the title of
the help text.

3 years agoinclude/opt: Improve code readability
Matthias Kruk [Thu, 11 Aug 2022 17:57:48 +0000 (02:57 +0900)]
include/opt: Improve code readability

There are several functions in the opt module where local variables
are not declared in the most narrow block possible, statements are
needlessly spread over multiple lines, and values used only once
are assigned to variables; all of which impeding readability.

This commit modifies the opt module to remove cases of assign-once-
read-once variables, remove integer increments on separate lines,
make the "scope" of variables narrower, and declare variables
with a type, where possible.

3 years agoinclude/opt: Remove unnecessary array __opt_long
Matthias Kruk [Thu, 11 Aug 2022 17:48:34 +0000 (02:48 +0900)]
include/opt: Remove unnecessary array __opt_long

The data that is stored in opt's __opt_long array is a subset of
the data stored in __opt_map. The operations that the module does
on __opt_long might just as well be performed on __opt_map without
affecting the behavior of the module.

This commit removes the __opt_long array from the module and
changes the affected functions to use __opt_map instead.

3 years agoinclude/opt: Show default values in help text
Matthias Kruk [Thu, 11 Aug 2022 17:46:52 +0000 (02:46 +0900)]
include/opt: Show default values in help text

The opt module does not show the default values of options in the
help text, leaving the user guessing what the values of options are
if they are not specified on the command line.

This commit modifies `opt_print_help()` so that it displays the
default values of options that have a value and a default set.

3 years agoinclude/opt: Use associative array to track missing options
Matthias Kruk [Thu, 11 Aug 2022 17:09:07 +0000 (02:09 +0900)]
include/opt: Use associative array to track missing options

The opt module does not track missing options, but instead checks
on demand if required options are missing by inspecting all options'
flags and value. This approach is needlessly complicated and slow.

This commit changes the opt module to track required options using
an associative array, allowing the check for missing options to be
performed in constant time.

3 years agoinclude/opt: Use an associative array to simplify flag parsing
Matthias Kruk [Thu, 11 Aug 2022 16:54:00 +0000 (01:54 +0900)]
include/opt: Use an associative array to simplify flag parsing

When parsing the flags of an option, the opt module uses a case
construct, which looks clumsy, isn't very easy to read, and makes
adding new flags more complicated than need be.

This commit modifies the opt module to use an associative array
to simplify flag parsing. This way, the parser only has to use a
flag as index into the array in order to find out its internal
value.

3 years agoinclude/opt: Remove unused variable __opt_num
Matthias Kruk [Thu, 11 Aug 2022 16:38:04 +0000 (01:38 +0900)]
include/opt: Remove unused variable __opt_num

The opt module counts the number of options that were defined, but
the count is never used.

This commit removes the unused variable.

3 years agotest/opt: Add test cases for opt module
Matthias Kruk [Thu, 11 Aug 2022 13:13:44 +0000 (22:13 +0900)]
test/opt: Add test cases for opt module

There are currently no test cases, making it difficult to verify
automatically if the opt module is implemented correctly, and to
detect regressions.

This commit adds a set of shellspec test cases for the opt module.

3 years agoinclude/opt: Make return values of opt_get() more helpful
Matthias Kruk [Thu, 11 Aug 2022 13:06:36 +0000 (22:06 +0900)]
include/opt: Make return values of opt_get() more helpful

The function `opt_get()` returns 0 when an option is valid but was
not set. This makes it impossible to distinguish if the value of
the option is the empty string or it does not have a value at all.
Further, it does not return an error if an invalid option's value
was requested.

This commit fixes the behavior of `opt_get()` so that it returns 0
if an option is valid and has a value (default or user-defined), 1
in case that the option name is invalid, and 2 in case that the
option name is valid but it does not have a value.

3 years agoinclude/opt: Emit an error if a required parameter is missing
Matthias Kruk [Thu, 11 Aug 2022 12:47:38 +0000 (21:47 +0900)]
include/opt: Emit an error if a required parameter is missing

When an option expecting a parameter is not passed one, `opt_parse()`
does not fail because of an incorrect comparison.

This commit fixes the comparison so that `opt_parse()` fails and
prints an error message when a required parameter is missing.

3 years agoinclude/opt: Emit an error message when an option is redefined
Matthias Kruk [Thu, 11 Aug 2022 12:27:49 +0000 (21:27 +0900)]
include/opt: Emit an error message when an option is redefined

When the caller attempts to redefine an option, `opt_add_arg()` fails
without printing an error message, leaving the situation undetected
if the caller does not check the return value of the call.

This commit modifies `opt_add_arg()` to print an error message when
a caller attempts to redefine an option.

3 years agoinclude/opt: Use column command to align help text
Matthias Kruk [Thu, 11 Aug 2022 11:48:17 +0000 (20:48 +0900)]
include/opt: Use column command to align help text

When printing the help text, the opt module aligns columns manually
by tracking the longest option name and inserting the required amount
of spaces into the output. This is needlessly complicated considering
there are simpler ways to align output.

This commit modifies the opt module to use the column command to
align the table of options in the help text.

3 years agoinclude/opt: Print correct script name on older bash versions
Matthias Kruk [Thu, 11 Aug 2022 11:18:02 +0000 (20:18 +0900)]
include/opt: Print correct script name on older bash versions

The opt module references $BASH_ARGV0 to get the name of the running
script. However, the variable does not exist on older bash versions,
causing a gap in the help text.

This commit modifies the opt module to access the script name from
$0, which should be available on all bash versions.

3 years agotoolbox.sh: Make command-not-found errors more helpful
Matthias Kruk [Sat, 9 Jul 2022 02:50:06 +0000 (11:50 +0900)]
toolbox.sh: Make command-not-found errors more helpful

Command-not-found errors often occur because the user forgot to
include a module. In such cases, it would be helpful if the default
error message included suggestions for modules to include.

This commit adds a `command_not_found_handle()` function that
overrides bash's default behavior: aside of the usual error message,
this function will print all module names that the missing function
may be part of (as determined by its name) to stderr.

3 years agoinclude/uipc: Add module for unsigned message-based IPC
Matthias Kruk [Sun, 27 Feb 2022 08:35:27 +0000 (17:35 +0900)]
include/uipc: Add module for unsigned message-based IPC

The IPC module cannot be used without GPG for message signing and
verification, which makes the module unusable if GPG cannot be used.

This commit adds the uipc module, which implements functions similar
to those of the ipc module, but without message authentication.

3 years agoinclude/inst: Expect arguments from opt_get_argv() in multiple lines
Matthias Kruk [Sun, 27 Feb 2022 09:02:18 +0000 (18:02 +0900)]
include/inst: Expect arguments from opt_get_argv() in multiple lines

The inst module expects `opt_get_argv()` to print all command line
arguments in one line, however the behavior of `opt_get_argv()` has
been changed to print arguments line-by-line.

This commit modifies the inst module so that it expects arguments to
be returned one per line by `opt_get_argv()`.

3 years agoinclude/opt: Make opt_get_argv() print arguments line-by-line
Matthias Kruk [Sun, 27 Feb 2022 08:59:27 +0000 (17:59 +0900)]
include/opt: Make opt_get_argv() print arguments line-by-line

Because `opt_get_argv()` prints the entire command line in one line,
callers cannot reliably parse individual arguments from the output.

This commit modifies `opt_get_argv()` to print the arguments line-
by-line.

3 years agoinclude/ipc: Remove unnecessary variables in _ipc_msg_new()
Matthias Kruk [Sun, 27 Feb 2022 08:46:47 +0000 (17:46 +0900)]
include/ipc: Remove unnecessary variables in _ipc_msg_new()

The `_ipc_msg_new()` function has one duplicate and one unused
variable declaration that can be removed.

This commit removes the unnecessary variable declarations from
`_ipc_msg_new()`.

3 years agoinclude/log: Don't mangle whitespaces
Matthias Kruk [Tue, 15 Feb 2022 01:33:36 +0000 (10:33 +0900)]
include/log: Don't mangle whitespaces

Because IFS is not set in `_log_write()`, logging functions silently
drop whitespace from the beginning and end of each line.

This commit modifies `_log_write()` to set IFS to the empty string
when invoking `read`, so that whitespaces are not stripped.

3 years agoinclude/mutex: Use $$ instead of $BASHPID to identify the owner
Matthias Kruk [Mon, 14 Feb 2022 10:52:14 +0000 (19:52 +0900)]
include/mutex: Use $$ instead of $BASHPID to identify the owner

The mutex module uses $BASHPID to identify the owner of a mutex,
causing scripts to be unable to unlock a mutex that was created in a
subshell (which is what happens when using the ipc module).

This commit changes the mutex module to use $$ to identify the owner
of a mutex, allowing child processes to unlock their parent's mutexes
and vice-versa.

3 years agoinclude/ipc: Fix bug in unsubscribe logic when closing an endpoint
Matthias Kruk [Mon, 14 Feb 2022 10:42:56 +0000 (19:42 +0900)]
include/ipc: Fix bug in unsubscribe logic when closing an endpoint

When `ipc_endpoint_close()` attempts to remove all subscriptions of
an endpoint, the list that it iterates over includes the directory
containing the subscriptions, causing the function to emit an error.

This commit fixes the way that `ipc_endpoint_close()` determines the
list of subscriptions to be removed.

3 years agoinclude/array: Improve performance of array_to_lines()
Matthias Kruk [Wed, 2 Feb 2022 11:20:12 +0000 (20:20 +0900)]
include/array: Improve performance of array_to_lines()

`array_to_lines()` calls `echo` for every element in the array, which
is wasteful and scales very poorly.

This commit modifies `array_to_lines()` so that it uses a single call
to `printf` to print all array elements.

This issue was pointed out by reddit user u/oh5nxo.

3 years agoREADME: Add note about GPG keys to configuration section
Matthias Kruk [Tue, 1 Feb 2022 03:48:23 +0000 (12:48 +0900)]
README: Add note about GPG keys to configuration section

To use the ipc module, users need to have a usable gpg keypair, but
the README does not mention that.

This commit adds a paragraph about GPG to the configuration section
of the README.

3 years agodebian: Make toolbox package depend on gnupg2
Matthias Kruk [Tue, 1 Feb 2022 03:25:02 +0000 (12:25 +0900)]
debian: Make toolbox package depend on gnupg2

The ipc module uses gpg2, but gnupg2 is not among the dependencies
of the toolbox package.

This commit adds gnupg2 to the dependencies of the toolbox package.

3 years agoREADME: Add a usage example
Matthias Kruk [Mon, 31 Jan 2022 17:17:52 +0000 (02:17 +0900)]
README: Add a usage example

The readme does not explain how to use toolbox.

This commit adds two short examples how to use toolbox.

3 years agoAdd README file
Matthias Kruk [Mon, 31 Jan 2022 17:01:07 +0000 (02:01 +0900)]
Add README file

The repository does not have a README file, making it hard for users
to understand what toolbox is, how it works, and what modules there
are.

This commit adds a README that explains what toolbox is, how it can
be installed, and what modules there are.

3 years agodebian: Don't create/remove groups during upgrades/downgrades
Matthias Kruk [Sat, 22 Jan 2022 07:48:46 +0000 (16:48 +0900)]
debian: Don't create/remove groups during upgrades/downgrades

The debian maintainer scripts remove and create group during upgrades
and downgrades, causing the group ids to change, locking users out of
/var/lib/toolbox.

This commit modifies the debian maintainer scripts so that they only
remove groups during package removals.

3 years agodebian: Make postinst and postrm scripts use dpkg-statoverride
Matthias Kruk [Fri, 21 Jan 2022 10:15:06 +0000 (19:15 +0900)]
debian: Make postinst and postrm scripts use dpkg-statoverride

The postinst and postrm scripts change the ownership and permissions
of /var/lib/toolbox directly, which is discouraged behavior.

This commit changes the scripts so they use dpkg-statoverride instead.

3 years agodebian: Add/remove groups during installation/removal
Matthias Kruk [Fri, 21 Jan 2022 09:55:39 +0000 (18:55 +0900)]
debian: Add/remove groups during installation/removal

When installing toolbox from debian packages, the toolbox and
toolbox_ipc groups are not created, and the permissions and
ownership of /var/lib/toolbox are incorrect.

This commit adds postinst and postrm scripts that create and remove
the toolbox and toolbox_ipc groups during installation/removal, and
set the permissions on /var/lib/toolbox appropriately.

3 years agoinclude/git: Add git_remote_get() function
Matthias Kruk [Fri, 7 Jan 2022 13:37:00 +0000 (22:37 +0900)]
include/git: Add git_remote_get() function

This commit adds the git_remote_get() function, which can be used to
determine the URLs of a repository's remotes.

3 years agoinclude/git: Add git_commit() function
Matthias Kruk [Fri, 7 Jan 2022 13:32:13 +0000 (22:32 +0900)]
include/git: Add git_commit() function

This commit adds the git_commit() function, which commits all staged
changes to the current branch.

3 years agoinclude/git: Rename functions operating on branches to git_branch_*
Matthias Kruk [Fri, 7 Jan 2022 13:20:55 +0000 (22:20 +0900)]
include/git: Rename functions operating on branches to git_branch_*

Functions that operate on branches should be named accordingly to
make their purpose clear.

This commit renames the following functions.
 * git_current_branch() -> git_branch_get_current()
 * git_checkout()       -> git_branch_checkout()

4 years agoMerge branch 'master' into unstable
Matthias Kruk [Thu, 2 Dec 2021 03:04:48 +0000 (12:04 +0900)]
Merge branch 'master' into unstable

Merge the master branch back into unstable in order to increase the
debian package version.

4 years agoinclude/is: Add is_int() function
Matthias Kruk [Thu, 2 Dec 2021 03:00:24 +0000 (12:00 +0900)]
include/is: Add is_int() function

The is_digits() function provided by the "is" module can be used to
determine if an input consists of only digits. However, it cannot be
used to validate inputs that may be prefixed with a sign.
This commit adds the is_int() function, which can be used to validate
numeric inputs that may be prefixed with a sign.

4 years agodebian: Increase package version to 0.3.2-1 stable
Matthias Kruk [Wed, 1 Dec 2021 11:51:15 +0000 (20:51 +0900)]
debian: Increase package version to 0.3.2-1

This commit increases the package version to 0.3.2-1.

4 years agoinclude/ipc: Use the endpoint name as name for pubsub subscriptions
Matthias Kruk [Wed, 1 Dec 2021 09:40:28 +0000 (18:40 +0900)]
include/ipc: Use the endpoint name as name for pubsub subscriptions

When subscribing to a pubsub channel, a name constructed from the
hostname and pid is used for the subscription name. When multiple
processes subscribe to the same topic using the same endpoint, this
causes the endpoint to be subscribed multiple times, and multiple
messages to be received by the endpoint, when it should only receive
one message (this usage is intended for load-balancing over pubsub
channels).
This commit modifies the ipc module so that the name of the endpoint
is used for the subscription name, preventing an endpoint from being
subscribed multiple times to the same topic.

4 years agoinclude/ipc: Don't dereference symlinks when subscribing to a topic
Matthias Kruk [Tue, 30 Nov 2021 13:07:29 +0000 (22:07 +0900)]
include/ipc: Don't dereference symlinks when subscribing to a topic

The `_ipc_endpoint_topic_subscribe()' function dereferences symbolic
links when subscribing to a topic, causing symbolic links to be
created in the wrong directory if the topic already exists.
This commit changes the flags that `_ipc_endpoint_topic_subscribe()'
passes to `ln' so that the target won't be dereferenced if it refers
to a symbolic link.

4 years agodebian: Increase package version to 0.3.1-1
Matthias Kruk [Thu, 25 Nov 2021 05:36:16 +0000 (14:36 +0900)]
debian: Increase package version to 0.3.1-1

This commit increases the package version to 0.3.1-1 and adds missing
dependencies to the debian/control file.

4 years agoMakefile: Disable tests during build process
Matthias Kruk [Thu, 25 Nov 2021 05:25:08 +0000 (14:25 +0900)]
Makefile: Disable tests during build process

The test suite is executed automatically by dpkg-buildpackage during
the build process. However, because the test framework is not set up
on the build machine, this causes the packaging process to fail.
This commit removes the test rule from the Makefile to avoid issues
with the build system until the test framework is set up.

4 years agoinclude/ipc: Add GPLv3 notice
Matthias Kruk [Thu, 25 Nov 2021 04:45:42 +0000 (13:45 +0900)]
include/ipc: Add GPLv3 notice

The ipc module does not have a license header, making it hard to tell
what license the code was published under if the file ever gets separated.
This commit adds a license header to the ipc module.

4 years agoinclude/git: Add module for interaction with git repositories
Matthias Kruk [Sun, 8 Aug 2021 06:30:36 +0000 (15:30 +0900)]
include/git: Add module for interaction with git repositories

This commit adds a module that can be used to perform operations such
as cloning, merging, pushing, etc on a git repository without having
to change directories.

4 years agoinclude/git: Add module for interaction with git repositories
Matthias Kruk [Sun, 1 Aug 2021 22:12:02 +0000 (07:12 +0900)]
include/git: Add module for interaction with git repositories

This commit adds the git module, which implements a set of functions
to simplify interaction with git repositories.

4 years agoinclude/conf: Add function to get available configuration entries
Matthias Kruk [Sat, 24 Jul 2021 06:27:29 +0000 (15:27 +0900)]
include/conf: Add function to get available configuration entries

The conf module currently does not provide a means to figure out what
configuration entries are available.
This commit adds a method that allows the caller to figure out what
configuration settings are available in a given configuration domain.

4 years agoinclude/ipc: Add ipc_endpoint_foreach_message() function
Matthias Kruk [Sat, 24 Jul 2021 04:46:20 +0000 (13:46 +0900)]
include/ipc: Add ipc_endpoint_foreach_message() function

The IPC module currently does not provide an API that can be used
to enquire the state of the queue of an endpoint. This makes it
unnecessarily complicated to implement monitoring of IPC endpoints.
This commit adds the ipc_endpoint_foreach_message() function that
may be used to enquire about messages that are stored in the internal
queue of an IPC endpoint. The semantics of this function are similar
to those of queue_foreach(), with the exception that the endpoint
name is passed in the first parameter of the callback and the message
in the second parameter. The remaining parameters are passed on from
ipc_endpoint_foreach_message().

4 years agoinclude/conf: Add support for multiple configuration files
Matthias Kruk [Sat, 24 Jul 2021 04:21:27 +0000 (13:21 +0900)]
include/conf: Add support for multiple configuration files

The current conf implementation does not permit processes to use
more than one configuration file.
This commit modifies the conf module so that each process may use
an arbitrary number of configuration files by appending the name of
a config domain to the commandline of commands such as conf_get()
and conf_set(), falling back to "default" if the config domain was
omitted.
This commit further adds the conf_get_domains() method that may be
used to query the names of known configuration domains.

4 years agoinclude/inst: Make instances trap signals
Matthias Kruk [Sat, 24 Jul 2021 04:05:55 +0000 (13:05 +0900)]
include/inst: Make instances trap signals

Instances don't handle signals, causing them not to get cleaned up
properly when terminated by a signal.
This commit adds a signal handler to the inst module, making sure
instances are properly cleaned up when terminated by a signal.

4 years agoinclude/inst: Make subsequent calls to inst_running() return false
Matthias Kruk [Thu, 22 Jul 2021 23:21:48 +0000 (08:21 +0900)]
include/inst: Make subsequent calls to inst_running() return false

When an instance is instructed to stop, a semaphore is increased to
signal this condition. The inst_running() function uses sem_trywait()
on this semaphore, returning false if the semaphore could be passed,
thus telling the caller that the instance should be stopped.
However, since sem_trywait() decreases the semaphore, subsequent calls
to inst_running() will return true again.
This commit changes inst_running() to increase the semaphore in case
it was decreased by sem_trywait(). However, there remains a small
window of opportunity where the function may return different values
to different callers if multiple processes from the same instance call
the function at the same time.

4 years agoinclude/inst: Allow functions to be used on foreign instances
Matthias Kruk [Thu, 22 Jul 2021 23:09:14 +0000 (08:09 +0900)]
include/inst: Allow functions to be used on foreign instances

Functions of the inst module assume that instances of the current
script are supposed to be manipulated. This makes it impossible for
the functions to be used to enquire or manipulate instances of other
scripts.
This commit changes the functions (where it makes sense) so they can
be used to operate on instances of scripts other than the one that is
executing them.

4 years agotest/array: Add new test cases for the array module
Matthias Kruk [Fri, 9 Jul 2021 00:09:17 +0000 (09:09 +0900)]
test/array: Add new test cases for the array module

There are no shellspec test cases for the array module.
This commit adds test cases for all functions of the public API of the
array module.

4 years agotest/json: Fix test cases for json module
Matthias Kruk [Thu, 8 Jul 2021 22:50:49 +0000 (07:50 +0900)]
test/json: Fix test cases for json module

Several of the test cases for the json module are calling the wrong
functions. Further, there are no test cases for type specifiers in
json_object() and json_array().
This commit fixes test cases that are calling the wrong functions and
adds test cases for type specifiers.

4 years agoinclude/json: Introduce type specifiers
Matthias Kruk [Wed, 7 Jul 2021 00:18:03 +0000 (09:18 +0900)]
include/json: Introduce type specifiers

When constructing JSON objects and arrays, there are cases where the
json_object() and json_array() functions cannot correctly determine
the type of a variable (for example, "true" could be string or bool).
This commit introduces type specifiers that allow the user to declare
the type of a value that is passed to the json functions.
Specifiers are prepended to the value when passing it to the
json_object() json_array() functions. The following specifiers are
understood:

 - "s:" string
 - "i:" integer
 - "b:" boolean
 - "f:" float
 - "o:" object
 - "a:" array

The following is how the specifiers are passed.

 json_object "some_string"  "s:$some_string" \
             "some_integer" "i:$some_integer"

For backwards compatibility, the specifiers may be omitted. In that
case, a best-effort guess will be made. Omitting type specifiers will
make it impossible to pass certain values in strings.

4 years agoinclude/json: Allow false booleans to be retrieved from JSON types
Matthias Kruk [Tue, 6 Jul 2021 22:56:43 +0000 (07:56 +0900)]
include/json: Allow false booleans to be retrieved from JSON types

Because of the way the return value of jq is checked in
json_object_get() and json_array_head(), the functions will fail if a
value of (boolean) "false" was retrieved from the JSON type.
This commit fixes the behavior of json_object_get() and
json_array_head() so that false booleans can be retrieved.

4 years agotest/json: Add test suite for json module
Matthias Kruk [Mon, 5 Jul 2021 23:48:32 +0000 (08:48 +0900)]
test/json: Add test suite for json module

This commit adds a set of test cases for the json object. It tests the
primary properties of all functions that are part of the module's
public API.

4 years agotest: Use shellspec as the default test framework
Matthias Kruk [Sun, 4 Jul 2021 23:48:59 +0000 (08:48 +0900)]
test: Use shellspec as the default test framework

There are issues with bats when accessing device files such as
/dev/urandom, making it hard to implement tests that require randomness.
This commit modifies test.sh to use shellspec as the default test
framework.

4 years agoinclude: Remove ssh module
Matthias Kruk [Sun, 4 Jul 2021 23:26:06 +0000 (08:26 +0900)]
include: Remove ssh module

To avoid the dependency on ssh, this commit removes the ssh module
from the toolbox core package. The module will be moved to a separate
repository, presumably something along the lines of toolbox-goodies.

4 years agoinclude/json: Add json_object_get() function
Matthias Kruk [Sun, 4 Jul 2021 23:01:01 +0000 (08:01 +0900)]
include/json: Add json_object_get() function

The json module doesn't provide any functions to retrieve data from
within JSON types, requiring users to call jq (or other parsers)
directly.
This commit adds the json_object_get() function, which allows the user
to retrieve the value of a field in a JSON object.

4 years agotest/queue: Add unit tests for queue functions
Matthias Kruk [Wed, 30 Jun 2021 22:48:10 +0000 (07:48 +0900)]
test/queue: Add unit tests for queue functions

This commit adds unit tests to verify the behavior of all functions of
the public API of the queue module.

4 years agoinclude/queue: Correctly handle omitted timeout in queue_get_file()
Matthias Kruk [Wed, 30 Jun 2021 22:36:10 +0000 (07:36 +0900)]
include/queue: Correctly handle omitted timeout in queue_get_file()

The queue_get_file() function does not correctly interpret the timeout
as infinity if the parameter is omitted.
This commit adds a check to queue_get_file() so that the timeout is
set correctly if the parameter is omitted.

4 years agoinclude/queue: Don't allow passing data along with files
Matthias Kruk [Wed, 30 Jun 2021 22:27:39 +0000 (07:27 +0900)]
include/queue: Don't allow passing data along with files

The queue implementation allows data to be passed along with files in
a queue. This increases the complexity of the queue implementation and
taints the API since the return value from queue_get_file() can't be
used without splitting it first.
This commit removes user-data passing from queue_put_file() and
queue_get_file().

4 years agotest/queue: Add test cases for several queue functions
Matthias Kruk [Tue, 29 Jun 2021 00:26:08 +0000 (09:26 +0900)]
test/queue: Add test cases for several queue functions

To ensure that the queue module behaves as intended, test cases are
needed.
This commit adds test cases to test the behavior of the following
functions.
 - queue_init()
 - queue_destroy()
 - queue_put()
 - queue_put_unique()
 - queue_put_file()
 - queue_get()
 - queue_foreach()

4 years agoinclude/queue: Prevent queue_put_unique() from adding duplicates
Matthias Kruk [Mon, 28 Jun 2021 23:28:23 +0000 (08:28 +0900)]
include/queue: Prevent queue_put_unique() from adding duplicates

There are several issues in _queue_contains(), causing the
queue_put_unique() function to hang (waiting for input from stdin) or
add duplicate items to the queue.
This commit addresses these issues so that queue_put_unique() does not
hang or add duplicate items.

4 years agoinclude/array: Add functions for comparing two arrays
Matthias Kruk [Mon, 28 Jun 2021 21:57:38 +0000 (06:57 +0900)]
include/array: Add functions for comparing two arrays

This commit adds the array_same() and array_identical() functions to
the array module. The former allows the caller to determine if two
arrays contain the same elements (i.e. permutations are accepted)
while the latter function does not permit permutations.

4 years agoinclude: Remove acpi/*, clip, gitlab, iruca, net/*, xrandr modules
Matthias Kruk [Sun, 27 Jun 2021 08:05:57 +0000 (17:05 +0900)]
include: Remove acpi/*, clip, gitlab, iruca, net/*, xrandr modules

To avoid dependencies on packages such as X11 in the toolbox core
package, several packages need to be moved into separate repositories.
This commit removes the following modules from this repository:
 - acpi/ac      => toolbox-linux
 - acpi/battery => toolbox->linux
 - clip         => toolbox-x11
 - gitlab       => toolbox-restapis
 - iruca        => toolbox-restapis
 - net/iface    => toolbox-linux
 - xrandr       => toolbox-x11

4 years agoinclude/queue: Fix missing arrowheads in documentation
Matthias Kruk [Sun, 27 Jun 2021 07:35:28 +0000 (16:35 +0900)]
include/queue: Fix missing arrowheads in documentation

The petri net in the comment explaining the queue internals are
missing arrowheads. This may cause confusion since edges in petri
nets are usually directed.
This commit adds the missing arrowheads to the petri net.

4 years agotest/is: Add shellspec test cases for "is" module
Matthias Kruk [Sun, 20 Jun 2021 06:01:45 +0000 (15:01 +0900)]
test/is: Add shellspec test cases for "is" module

The test cases for the "is" module are implemented for BATS, but going
forward shellspec should be used.
This commit migrates the previous test cases from BATS to shellspec and
adds test cases for the is_base64() function.

4 years agoinclude/ipc: Use endpoints to implement publish-subscribe functions
Matthias Kruk [Sun, 27 Jun 2021 01:35:41 +0000 (10:35 +0900)]
include/ipc: Use endpoints to implement publish-subscribe functions

The publish-subscribe functions added by the previous commit are
independent of the endpoint API, making it necessary to separately
implement authentication and message encapsulation for pubsub
messaging.
This commit moves the pubsub functionality into the endpoint API,
making it unnecessary to re-implement message authentication and
encapsulation.

4 years agoinclude/ipc: Add publish-subscribe channel implementation
Matthias Kruk [Sat, 26 Jun 2021 10:10:33 +0000 (19:10 +0900)]
include/ipc: Add publish-subscribe channel implementation

This commit adds a naive queue-based pubsub implementation that allows
scripts to send messages to multiple receivers at a time.

4 years agotest/log: Add test suite for public API of log module
Matthias Kruk [Sat, 26 Jun 2021 03:18:49 +0000 (12:18 +0900)]
test/log: Add test suite for public API of log module

This commit adds a test suite with test cases to test all functions
that are part of the public API of the log module.

4 years agoinclude/log: Fix invalid decision to read from stdin in log_highlight()
Matthias Kruk [Sat, 26 Jun 2021 01:58:11 +0000 (10:58 +0900)]
include/log: Fix invalid decision to read from stdin in log_highlight()

Because the boundaries aren't correct, log_highlight() will attempt to
read input from stdin if only one line was passed in positional
parameters.
This commit fixes the boundary so that log_highlight() will print any
number of lines correctly, whether passed in positional parameters or
via stdin.

4 years agoinclude/log: Remove log_write() from public API
Matthias Kruk [Thu, 24 Jun 2021 23:46:58 +0000 (08:46 +0900)]
include/log: Remove log_write() from public API

The log_write() function is not intended to be used directly, so it
should not be part of the public API of the log module.
This commit makes the log_write() function private by renaming it to
_log_write() and updating all references to it.

4 years agoinclude/log: Fix indentation in log_stacktrace()
Matthias Kruk [Thu, 24 Jun 2021 23:44:26 +0000 (08:44 +0900)]
include/log: Fix indentation in log_stacktrace()

Stacktraces printed by log_stacktrace() are not indented correctly
because of a typo in the statement that increases the indentation.
This commit fixes the typo so that lines are indented correctly.

4 years agoinclude: Explicitly declare arguments at the top of all functions
Matthias Kruk [Thu, 24 Jun 2021 23:40:01 +0000 (08:40 +0900)]
include: Explicitly declare arguments at the top of all functions

Several functions do not declare and assign all arguments at the top,
violating the toolbox coding style.
This commit changes all argument declarations so that they conform to
the toolbox style.

4 years agoinclude/{opt,inst}: Add regex parameter to opt_add_arg() calls
Matthias Kruk [Mon, 21 Jun 2021 23:49:42 +0000 (08:49 +0900)]
include/{opt,inst}: Add regex parameter to opt_add_arg() calls

The opt and inst modules use opt_add_arg() to register command line
arguments with a callback, however they omit the newly-added regex
argument, causing the callbacks not to be called.
This commit fixes the order of arguments passed to opt_add_arg() so
that the command line arguments are registered correctly.

4 years agotest/ipc: Add test cases for IPC endpoints
Matthias Kruk [Mon, 21 Jun 2021 12:13:29 +0000 (21:13 +0900)]
test/ipc: Add test cases for IPC endpoints

Functions that operate on IPC endpoints are not covered by any of the
test cases in the ipc_spec.sh test suite.
This commit adds a set of test cases that test the following functions.
 - ipc_endpoint_open()
 - ipc_endpoint_close()
 - ipc_endpoint_send()
 - ipc_endpoint_recv()

4 years agoinclude/opt: Implement argument validation using regular expressions
Matthias Kruk [Mon, 21 Jun 2021 11:27:57 +0000 (20:27 +0900)]
include/opt: Implement argument validation using regular expressions

The opt_parse() function does not implement validation of commandline
arguments, leaving it to the caller to sanitize values passed by the
user.
This commit adds an argument to opt_add_arg() that allows the caller
to specify a regular expression that will be used by opt_parse() to
validate user inputs.

4 years agotest/ipc: Add test cases for ipc_msg_* functions
Matthias Kruk [Fri, 18 Jun 2021 23:52:29 +0000 (08:52 +0900)]
test/ipc: Add test cases for ipc_msg_* functions

This commit adds test cases to ensure that ipc_msg_* functions work as
intended. The following functions are covered by the test cases.
 - ipc_msg_get_version()
 - ipc_msg_get_source()
 - ipc_msg_get_destination()
 - ipc_msg_get_user()
 - ipc_msg_get_timestamp()
 - ipc_msg_get_data()
 - ipc_msg_get_signer_name()
 - ipc_msg_get_signer_email()
 - ipc_msg_get_signer_key()

4 years agotest/ipc: Add test cases to validate messages against JSON schema
Matthias Kruk [Fri, 18 Jun 2021 23:02:47 +0000 (08:02 +0900)]
test/ipc: Add test cases to validate messages against JSON schema

This commit adds unit tests to make sure that messages generated by
the IPC module are conforming to the toolbox.ipc JSON schemas.

4 years agospec/ipc: Rename base message schema to ipc_message / ipc.message.json
Matthias Kruk [Fri, 18 Jun 2021 22:55:49 +0000 (07:55 +0900)]
spec/ipc: Rename base message schema to ipc_message / ipc.message.json

IPC base messages are stored in the "message" field of an envelope,
and the schema for the latter is called ipc.envelope.json (and the
file is called ipc_envelope.schema.json). In keeping with that
convention, the schema for IPC base messages should be called
ipc.message.json (filename ipc_message.schema.json).
This commit makes sure the naming conventions are adhered to.

4 years agoinclude/is: Add is_base64() function
Matthias Kruk [Fri, 18 Jun 2021 07:25:08 +0000 (16:25 +0900)]
include/is: Add is_base64() function

This commit adds is_base64(), a convenience function that allows the
caller to check if a string is base64 encoded.

4 years agoinclude/ipc: Fix invalid function reference
Matthias Kruk [Fri, 18 Jun 2021 07:20:23 +0000 (16:20 +0900)]
include/ipc: Fix invalid function reference

The ipc_endpoint_recv() function calls _ipc_msg_validate(), which has
been renamed to ipc_msg_validate().
This commit fixes the reference so that the correct function is called.

4 years agoinclude/{mutex,wmutex,queue,sem}: Fix timeout behavior of blocking calls
Matthias Kruk [Fri, 18 Jun 2021 07:15:24 +0000 (16:15 +0900)]
include/{mutex,wmutex,queue,sem}: Fix timeout behavior of blocking calls

Because of a bug in the timeout handling, the mutex_lock(),
wmutex_lock(), queue_get(), and sem_wait() functions wait forever if a
positive timeout is specified.
This commit changes the behavior so that the functions will wait
forever if the timeout is -1 or omitted, return immediately if the
timeout is zero, or otherwise wait for the specified number of seconds.

4 years agotest/ipc: Add unit tests for message encoding and authentication
Matthias Kruk [Fri, 18 Jun 2021 00:33:53 +0000 (09:33 +0900)]
test/ipc: Add unit tests for message encoding and authentication

This commit adds unit tests that ensure that the following function
from the ipc module work as intended:
 - _ipc_encode()
 - _ipc_decode()
 - _ipc_sign()
 - _ipc_verify()

4 years agoinclude/ipc: Ensure complete IPC message is signed
Matthias Kruk [Thu, 17 Jun 2021 00:09:42 +0000 (09:09 +0900)]
include/ipc: Ensure complete IPC message is signed

The current implementation does not sign fields other than the user
data in IPC messages. This makes it impossible to recognize if the
other fields have been tampered with.
This commit addresses the issue by wrapping the IPC message in an
envelope and putting the signature of the IPC message in the envelope.
This makes sure there is no unsigned data in the communication.

4 years agoinclude/ipc: Change IPC message format so that all data is signed
Matthias Kruk [Wed, 16 Jun 2021 23:05:23 +0000 (08:05 +0900)]
include/ipc: Change IPC message format so that all data is signed

In the current IPC message format, only the data field is signed,
causing changes to the other fields to go unnoticed by the signature
verification.
This commit adds a new message format in that the IPC message is
wrapped in an envelope, making sure that all data is authenticated
by the signature.

4 years agoinclude/ipc: Rename _ipc_msg_encode() and _ipc_msg_decode()
Matthias Kruk [Wed, 16 Jun 2021 22:02:25 +0000 (07:02 +0900)]
include/ipc: Rename _ipc_msg_encode() and _ipc_msg_decode()

The _ipc_msg_encode() and _ipc_msg_decode() functions are used to
encode and decode more than just IPC messages, so the function names
are somewhat inaccurate.
This commit renames the functions to _ipc_encode() and _ipc_decode(),
respectively.

4 years agoinclude/ipc: Clean up ipc_msg API
Matthias Kruk [Tue, 15 Jun 2021 23:23:55 +0000 (08:23 +0900)]
include/ipc: Clean up ipc_msg API

The ipc module currently doesn't provide functions to get all fields
contained within a message. Further, signature-related functions don't
return an error if the message is invalid or the signature could not be
retrieved for another reason.
This commit adds the missing functions to the public API of the ipc
module and fixes the behavior of signature related functions so the
caller can correctly determine if an error has occurred.

The following functions have been added:
 - ipc_msg_get_version()
 - ipc_msg_get_signature()
 - ipc_msg_get_signer_name()
 - ipc_msg_get_signer_email()
 - ipc_msg_get_signer_key()

4 years agoinclude/ipc: Simplify IPC endpoint API
Matthias Kruk [Tue, 15 Jun 2021 00:21:48 +0000 (09:21 +0900)]
include/ipc: Simplify IPC endpoint API

The current API of the ipc module expects the user to create an ipc_msg
and send that using the ipc_endpoint_send() function, however there is
nothing useful that can be done with an ipc_msg besides sending it, so
it makes no sense to have the user create the ipc_msg themselves.
Further, the ipc_endpoint_recv() function will return any received
ipc_msg to the user, including invalid or unauthenticated messages.
This commit changes the IPC endpoint API so that the user can pass the
data they intend to send right to ipc_endpoint_send() without having
to call ipc_msg_new(). Since ipc_msg_new() is not intended to be used
by the user directly, it is removed from the public API of the ipc
module.
Further, the ipc_endpoint_recv() function is modified to return only
valid, authenticated messages to the caller.

4 years agoinclude/ipc: Rename ipc_endpoint_new() to ipc_endpoint_open()
Matthias Kruk [Mon, 14 Jun 2021 23:31:38 +0000 (08:31 +0900)]
include/ipc: Rename ipc_endpoint_new() to ipc_endpoint_open()

The functions for creating new endpoints and freeing endpoints are
called ipc_endpoint_new() and ipc_endpoint_close(), which is not
intuitive.
This commit renames ipc_endpoint_new() to ipc_endpoint_open(), since
open/close is the terminology that is traditionally used in
communication APIs.

4 years agoinclude/ipc: Remove option to disable authentication
Matthias Kruk [Mon, 14 Jun 2021 22:53:00 +0000 (07:53 +0900)]
include/ipc: Remove option to disable authentication

Providing the option to disable authentication does not bring any real
benefits, while it adds code paths that need to be tested.
This commit removes the option to disable authentication.

4 years agotoolbox: Make have(), _try_include(), include() read-only
Matthias Kruk [Mon, 14 Jun 2021 21:23:02 +0000 (06:23 +0900)]
toolbox: Make have(), _try_include(), include() read-only

Functions from toolbox.sh may be redeclared, causing all sorts of
problems from simple bugs to security issues.
This commit makes sure the functions are declared read-only when
toolbox is loaded so the user can't shoot themself in the foot.

4 years agoinclude/ipc: Add module for messaging-based IPC
Matthias Kruk [Sun, 13 Jun 2021 23:57:28 +0000 (08:57 +0900)]
include/ipc: Add module for messaging-based IPC

This commit adds the ipc module, which implements a messaging-based
approach to IPC using JSON objects that are transmitted via queues.
The current implementation authenticates messages using GPG, which
allows simple GPG-based authorization schemes to be implemented on
top of this mechanism.
This commit includes a JSON Schema for toolbox IPC messages and a
Python script for validation, both of which will be integrated into
the test suite.

4 years agoinclude/inst: Add functions for implementing singleton daemons
Matthias Kruk [Sun, 13 Jun 2021 08:12:48 +0000 (17:12 +0900)]
include/inst: Add functions for implementing singleton daemons

The inst_start() function does not check if a process is already
running, making it unusable for the implementation of singleton
daemons.
This commit adds the inst_singleton() function, which allows the
caller to implement daemons which can only be run one at a time.

4 years agoCOPYING: Add GPLv3 license, copyright headers
Matthias Kruk [Thu, 10 Jun 2021 20:43:44 +0000 (05:43 +0900)]
COPYING: Add GPLv3 license, copyright headers

None of the source files currently makes any mention of license terms
that toolbox is published under. This commit adds the license text of
the GPLv3 and copyright headers to each of the source files (except
unit tests).