= Release History

== 3.2: February 6, 2025

 - Update MANPREFIX for FreeBSD
 - Format source using clang-format and rubocop
 - rsub(1) allow diff(1) behavior to be modified using RSUB_DIFF_ARGS
 - rsub(1) refactor based on patterns used in rinstall(1)
 - rsub(1) remove temporary source file
 - Ensure top-level directory permissions are not world-readable
 - Avoid leaving a NUL character at the end of local execution script
 - Use native strtonum(3) on MacOS

== 3.1: September 24, 2024

 - Add begin= and end= options
 - Add archive and restore options
 - Allow IPv6 addresses to be used in routes
 - Add out-of-bounds check to options
 - Use 'set -a' instead of 'sh -a' to avoid environment contamination
 - Enable parallel execution using background workers
 - rinstall(1) print name of missing source with absolute path
 - rinstall(1) adjust comments and error messages

== 3.0: February 26, 2024

 - Check for ssh-agent before updating _rutils
 - Correct use of getopt(3) to allow compact flags
 - Use RSET_HOST_CONNECT_ERROR to format failed connection or stagedir initialization
 - Use RSET_LABEL_EXEC_ERROR if ssh(1) or sh(1) terminates during script execution
 - Add log format variable '%s' for generated session ID
 - Remove '-l' option
 - Tests: use curl(1) on Linux
 - Detect and use native strlcpy(3), strlcat(3), arc4random(3) on Linux
 - Upload _rutils and exported paths in two steps for compatibility with busybox tar(1)
 - rsub(1): escape ampersands found in '-l' argument
 - rinstall(1) allow diff(1) behavior to be modified using RINSTALL_DIFF_ARGS
 - rinstall(1) add '-a' option for defining an alternate source location
 - rinstall(1) saving a file in $SD no longer depends the current directory
 - rinstall(1) failure running diff(1) no longer reports "files are different"

== 2.9: December 22, 2023

 - Add flag '-E' for overriding remote environment variables
 - rset(1)/renv(1) extended to store session-level state using name="value"
   arguments
 - renv(1) improved error handling, one variable per line
 - Immediately raise errors and abort if environment or environment_file options
   contain syntax errors
 - rinstall(1) downloads sources to the staging directory without a temporary
   file to avoid duplication
 - rinstall(1) prioritize curl with fallback to wget on Linux
 - rinstall(1) recreates file path when fetching over HTTP
 - rinstall(1) allows empty files to be installed
 - Only support '-l' flag with dry-run
 - New custom log format for each stage of execution defined by environment
   variables

== 2.8: November 13, 2023

 - No longer set ROUTE_LABEL, and LABEL on remote host
 - New renv(1) utility for validating environment variables
 - New environment_file option for defining variables
 - New environment option for defining variables inline
 - Improve parsing by prioritizing parameters before labels
 - '-l' requires an option value

== 2.7: October 28, 2023

 - Avoid opening temporary files twice
 - Connect to the hostname specified, not the primary label name
 - Do not start web server during dry run
 - Execute all hostnames specified on the command line
 - Support for hostname sequence ranges in routes file

== 2.6: September 6, 2023

 - rinstall: use wget with fallback to curl except for *BSD
 - configure: use TARGET_OS to override the output of uname(1)
 - MacOS: use tar -c --no-xattrs
 - Use mkstemp(3) to avoid compiler warnings
 - Add bundler/inline and install webrick locally to run tests

== 2.5: December 16, 2022

 - rinstall: ignore environment variable http_proxy
 - rinstall: Use shell getopts to parse arguments
 - Raise error if a label alias begins with a space

== 2.4: May 3, 2022

 - Formatting improvements to tests
 - Route labels may be a comma-separated list

== 2.3: November 17, 2021

 - Tweaks to unveil(2)
 - rinstall(1) accepts a directory instead of a target, similar to cp(1)

== 2.2: June 16, 2021

 - Raise an error if the output of local execution does not end with '\n'
 - Rename "Remote Sequential Execution Tool" to "Remote Staging Execution Tool"
 - Fix miniquark arg parsing on arm

== 2.1: April 3, 2021

 - New syntax for pln(5): special text can be defined between '{' and '}'
 - New local_interpreter option for executing script in a local context
   to generate text that is prepended to a label

== 2.0: February 26, 2021

 - Handle HTTP install from files in subdirectories
 - rinstall(1) always sets owner and mode if specified
 - Add '-e' option to stop execution if an interpreter returns non-zero

== 1.9: January 28, 2021

 - A variable list of hostnames is accepted instead of a host regex
 - label_pattern is specified using '-x'

== 1.8: December 16, 2020

 - Minor updates to miniquark
 - Fix build with gcc 10.2
 - Clean up socket and ssh session if /tmp is full on remote host

== 1.7: August 4, 2020

 - Simplify config.h by removing options for configuring an external web server
 - Add full support for DragonFly and NetBSD
 - Add support for Illumos/OpenIndiana as a target platform

== 1.6: July 22, 2020

 - Switch to build-in HTTP server: miniquark(1)

== 1.5: June 30, 2020

 - Fetch files from '_sources' on 127.0.0.1 to avoid IPv6 confusion
 - Require the ssh-agent(1) to be running with at least one unlocked key
 - New '-v' option prints HTTP log messages after each label is executed

== 1.4: May 29, 2020

 - Print filename and line number for pln(5) parse errors and
 - No longer permit leading spaces in pln(5) files
 - New '-t' option allows TTY access

== 1.3: March 26, 2020

 - rinstall(1) prints the name of the target if it does not already exist
 - Always list hostnames and labels, '-n' shows the components the regex matches

== 1.2: November 1, 2019

 - By default only labels beginning with [0-9a-z] are evaluated
 - New labelgrep(1) utility for searching a collection of pln(5) files

== 1.1: September 25, 2019

 - Move hosting from bitbucket.org to github.com
 - Rename tags from rset-X.Y to X.Y

== 1.0: February 9, 2019

 - Support Alpine Linux
 - Forcibly remove temporary staging directory
 - Set remote environment variable ROUTE_LABEL
 - Bundled _rutils scripts insist on absolute targets
 - rinstall(1) will not install an empty file

== 0.9: November 7, 2018

 - Use unveil(2) to sandbox the HTTP server
 - Raise error early if httpd binary is not found in search path
 - rinstall(1) properly displays a notification when updating a binary file
 - Locate _rutils scripts using the PATH environment variable

== 0.8: September 24, 2018

 - Bundled _rutils scripts uses mktemp(1) to avoid collisions
 - Bundled _rutils scrips handle spaces and most other special characters
 - rsub(1) also handles block replacements
 - Raise error if path export list is specified outside of a routes file

== 0.7: September 13, 2018

 - Confer limited trust to remote hosts by requiring that each route label
   specify the file paths to be shipped to each host
 - rinstall(1) skips the HTTP fetch if the file is found in the staging
   directory
 - Refactor to take advantage of pledge(2)
 - Add new utility script rsub(1)

== 0.6: August 30, 2018

 - Specify ('-ll') more than once to display options for each label
 - New '-F' option for specifying an ssh_config(5) file
 - Drop 'username' option; use ssh_config(5) instead
 - Drop 'install_url' option; override INSTALL_URL within scripts instead
 - Parse all files referenced in routes_file
 - Allow labels to be specified as a regex

== 0.5: August 27, 2018

 - Builds on Ubuntu Linux
 - rinstall reports an error and exit code 3 if file transfer fails
 - Parse pln(5) files without flex(1)
 - Raise error on Mac if rinstall(1) does not receive an HTTP 200 for a fetch
 - Inherit option state from the routes file

== 0.4: August 22, 2018

 - Provide instructions for handling a control socket that already exists
 - Builds on MacOS 10.13
 - Print informational message when _rutils is created
 - Update _rutils/rinstall if a newer version is available
 - Quickly continue if ssh master connection fails

== 0.3: August 17, 2018

 - A label may contain any character except for single or double quotes
 - Set SSH options UserKnownHostsFile=/dev/null,StrictHostKeyChecking=no
 - Shut down SSH master connection if SIGINT or SIGTERM are caught
 - Add ('-f') option for specifying the route file to parse
 - Always change to the directory where the route file is located
 - Builds on FreeBSD 11

== 0.2: August 11, 2018

 - Add dry run option ('-n') prints hosts and highlights regex match
 - Add list ('-l') option to list each label before execution
 - Change the current directory to temporary staging dir
 - Optionally specify a label name to run
 - Add a watchdog process for terminating the http server reliably

== 0.1: August 8, 2018

 - Initial release at https://bitbucket.org/eradman/rset
 - Basic tutorials at https://scriptedconfiguration.org/
 - Builds on OpenBSD 6.3, issues commands over SSH socket
 - Support for 'username', 'interpreter', 'execute_using'
 - tar sent of '_rutils' directory and installation over ephemeral HTTP server
