Skip to content

Commit

Permalink
Fix #186: allow continuation character in .conf files
Browse files Browse the repository at this point in the history
This change makes it possible to use the standard continuation character
in .conf files.  For example:

    service [23456]     \
         log:stderr     \
         <!pid/foo>     \
         bar            \
         -- This is the bar service, it depends on foo # comment that's dropped

Notice the additional support for comments on .conf lines.  If you use
the comment character today you must change to escape it.  Like this:

    service :2 foo -- Foo \#2

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
  • Loading branch information
troglobit committed Nov 19, 2022
1 parent f217794 commit 9046b6f
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 30 deletions.
20 changes: 19 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ Change Log
All relevant changes are documented in this file.


[4.4][UNRELEASED]
-----------------

> **Note:** this release contains changes to the `.conf` parser. If you
> have .conf file statements with comment character (`#`) in the command
> options or description, you must now escape them (`\#`).
### Changes
* Support for line continuation character `\` in .conf files, issue #186

service name:sysklogd [S123456789] \
env:-/etc/default/sysklogd \
syslogd -F $SYSLOGD_ARGS \
-- System log daemon

### Fixes


[4.3][] - 2022-05-15
--------------------

Expand Down Expand Up @@ -1152,7 +1170,7 @@ Major bug fix release.

* Initial release

[UNRELEASED]: https://github.com/troglobit/finit/compare/4.2...HEAD
[UNRELEASED]: https://github.com/troglobit/finit/compare/4.3...HEAD
[4.3]: https://github.com/troglobit/finit/compare/4.2...4.3
[4.2]: https://github.com/troglobit/finit/compare/4.1...4.2
[4.1]: https://github.com/troglobit/finit/compare/4.0...4.1
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ files in `/etc/finit.d`. Available, but not yet enabled, services can
be placed in `/etc/finit.d/available` and enabled by an operator using
the [initctl](#commands--status) tool.

> **Note:** as of Finit v4.4, .conf lines can be broken up using the
> standard UNIX continuation character (`\`), also trailing comments are
> now supported. The latter means you need to escape any hashes used in
> directives and descriptions (`\#`). For more on this and examples,
> see the finit.conf(5) manual or [doc/config.md](doc/config.md).
```ApacheConf
# Fallback if /etc/hostname is missing
host default
Expand Down
23 changes: 21 additions & 2 deletions doc/config.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Configuration
=============
Finit Configuration
===================

* [Introduction](#introduction)
* [Environment Variables](#environment-variables)
Expand Down Expand Up @@ -297,6 +297,25 @@ Linux kernel, or the name is misspelled.
Configuration File Syntax
-------------------------

The file format is line based, empty lines and comments, lines starting
with `#`, are ignored. A configuration directive starts with a keyword
followed by a space and the rest of the line is treated as the value.

As of Finit v4.4, configuration directives can be broken up in multiple
lines using the continuation character `\`, and trailing comments are
also allowed. Example:

```aconf
# Escape \# chars if you want them literal in, e.g., descriptions
service name:sysklogd [S123456789] \
env:-/etc/default/sysklogd \
syslogd -F $SYSLOGD_ARGS \
-- System log daemon \# 1 # Comments allowed now
```

The .conf files `/etc/finit.conf` and `/etc/finit.d/*` support the
following directives:

### Hostname

**Syntax:** `host <NAME>`, or `hostname <NAME>`
Expand Down
19 changes: 13 additions & 6 deletions man/finit.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,20 @@ Available services
Enabled services, symlinks from available
.El
.Sh FILE FORMAT
Lines starting with `#' are ignored. Note that end-of-line comments are
NOT supported, comments must be on a line of their own.
The file format is line based, empty lines and comments, lines starting
with `#', are ignored. A configuration directive starts with a keyword
followed by a space and the rest of the line is treated as the value.
.Pp
A configuration stanza must be on a single (long) line and
.Em cannot
be broken up in multiple lines by use of a backslash as the last
character.
As of Finit v4.4, configuration directives can be broken up in multiple
lines using the continuation character `\\', and trailing comments are
also allowed. Example:
.Bd -unfilled -offset indent
# Escape \\# chars if you want them literal in, e.g., descriptions
service name:sysklogd [S123456789] \\
env:-/etc/default/sysklogd \\
syslogd -F $SYSLOGD_ARGS \\
-- System log daemon \\# 1 # Comments allowed now
.Ed
.Sh DIRECTIVES
This section lists all supported configuration directives. There also exist
deprecated directives, see the Markdown documentation for details on these.
Expand Down
26 changes: 12 additions & 14 deletions src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,6 @@ static int parse_dynamic(char *line, struct rlimit rlimit[], char *file)
static int parse_conf(char *file, int is_rcsd)
{
struct rlimit rlimit[RLIMIT_NLIMITS];
char line[LINE_SIZE] = "";
FILE *fp;

fp = fopen(file, "r");
Expand All @@ -856,26 +855,25 @@ static int parse_conf(char *file, int is_rcsd)

dbg("*** Parsing %s", file);
while (!feof(fp)) {
char *x;
char *line;

if (!fgets(line, sizeof(line), fp))
line = fparseln(fp, NULL, NULL, NULL, FPARSELN_UNESCCOMM);
if (!line) {
warn("Reading %s", file);
continue;
}

chomp(line);
tabstospaces(line);
//DEV dbg("%s", line);

/* Skip comments, i.e. lines beginning with # */
if (MATCH_CMD(line, "#", x))
continue;
dbg("%s", line);

if (!parse_static(line, is_rcsd))
continue;
if (!parse_dynamic(line, is_rcsd ? rlimit : global_rlimit, file))
continue;
;
else if (!parse_dynamic(line, is_rcsd ? rlimit : global_rlimit, file))
;
else
parse_env(line);

/* Not static or dynamic conf, check if it is a global env. */
parse_env(line);
free(line);
}

fclose(fp);
Expand Down
6 changes: 3 additions & 3 deletions test/initctl-status-subset.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ test_add_one()

test_init

test_add_one "task manual:yes name:foo :1 serv -- Foo #1"
test_add_one "task manual:yes name:foo :2 serv -- Foo #2"
test_add_one "task manual:yes name:foo :3 serv -- Foo #3"
test_add_one "task manual:yes name:foo :1 serv -- Foo \#1"
test_add_one "task manual:yes name:foo :2 serv -- Foo \#2"
test_add_one "task manual:yes name:foo :3 serv -- Foo \#3"
test_add_one "task manual:yes name:foobar serv -- Foobar"

say 'Reload Finit'
Expand Down
15 changes: 11 additions & 4 deletions test/signal-service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,23 @@ test_teardown()
say "Test start $(date)"

say 'Ensure file system is cleared'
texec rm -f /tmp/usr1.log
run "rm -f /tmp/usr1.log"

# Verifies line continuation as well
say "Add service stanza in $FINIT_CONF"
texec sh -c "echo 'service [2345] kill:20 log service.sh -- Test service' > $FINIT_CONF"
run "echo 'service [2345] kill:20 \\
log service.sh \\
-- Test service' > $FINIT_CONF"
run "cat $FINIT_CONF"
#run "initctl debug"

say 'Reload Finit'
texec sh -c "initctl reload"
run "initctl reload"

#run "initctl status service.sh"

say 'Send SIGUSR1 to service...'
texec sh -c "initctl signal service.sh SIGUSR1"
run "initctl signal service.sh SIGUSR1"

# shellcheck disable=SC2016
retry 'assert "service.sh received SIGUSR" "$(texec cat /tmp/usr1.log)" = "USR1"' 10 1

0 comments on commit 9046b6f

Please sign in to comment.