1
0
Fork 0
mirror of https://github.com/pygos/init.git synced 2024-05-19 04:06:13 +02:00

Simplifiy service file syntax

Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
This commit is contained in:
David Oberhollenzer 2018-04-04 14:03:23 +02:00
parent ca7b7c15c5
commit 56e6004336
15 changed files with 247 additions and 247 deletions

View file

@ -37,15 +37,28 @@ static NORETURN void split_and_exec(char *cmd)
while (*cmd != '\0') {
argv[i++] = cmd; /* FIXME: buffer overflow!! */
while (*cmd != '\0' && !isspace(*cmd))
++cmd;
if (*cmd == '"') {
while (*cmd != '\0' && *cmd != '"') {
if (cmd[0] == '\\' && cmd[1] != '\0')
++cmd;
if (isspace(*cmd)) {
*(cmd++) = '\0';
while (isspace(*cmd))
++cmd;
}
if (*cmd == '"')
*(cmd++) = '\0';
unescape(argv[i - 1]);
} else {
while (*cmd != '\0' && *cmd != ' ')
++cmd;
if (*cmd == ' ')
*(cmd++) = '\0';
}
while (*cmd == ' ')
++cmd;
}
argv[i] = NULL;

View file

@ -68,20 +68,10 @@ typedef struct {
char *rdline(int fd, int argc, const char *const *argv);
/*
Split a line of the shape "key = value" into key and value part.
The key can contain alphanumeric characters and can be padded with
spaces or tabs.
The value can be either a sequence of alphanumeric characters, period
or underscore OR a string in quotation marks. For strings, the
quotation marks are removed and escape sequences are processed.
The value may also be padded with spaces or tabs but the line may not
contain anything else after the value, except for spaces, tabs or
the '#' symbol which is interpreted as start of a comment.
Remove double quotes ('"') from a string and substitute escape
sequences in between double quotes.
*/
int splitkv(char *line, char **key, char **value);
int unescape(char *src);
/*
Search through an array of enum_map_t entries to resolve a string to

View file

@ -28,10 +28,21 @@
#include "service.h"
#include "util.h"
static int try_unescape(char *arg, const char *filename, size_t lineno)
{
if (unescape(arg)) {
fprintf(stderr, "%s: %zu: malformed string constant\n",
filename, lineno);
return -1;
}
return 0;
}
static int svc_desc(service_t *svc, char *arg,
const char *filename, size_t lineno)
{
(void)filename; (void)lineno;
if (try_unescape(arg, filename, lineno))
return -1;
svc->desc = arg;
return 0;
}
@ -39,7 +50,8 @@ static int svc_desc(service_t *svc, char *arg,
static int svc_tty(service_t *svc, char *arg,
const char *filename, size_t lineno)
{
(void)filename; (void)lineno;
if (try_unescape(arg, filename, lineno))
return -1;
svc->ctty = arg;
return 0;
}
@ -63,8 +75,12 @@ static int svc_exec(service_t *svc, char *arg,
static int svc_before(service_t *svc, char *arg,
const char *filename, size_t lineno)
{
char **new = realloc(svc->before,
sizeof(char*) * (svc->num_before + 1));
char **new;
if (try_unescape(arg, filename, lineno))
return -1;
new = realloc(svc->before, sizeof(char*) * (svc->num_before + 1));
if (new == NULL) {
fprintf(stderr, "%s: %zu: out of memory\n", filename, lineno);
@ -80,7 +96,12 @@ static int svc_before(service_t *svc, char *arg,
static int svc_after(service_t *svc, char *arg,
const char *filename, size_t lineno)
{
char **new = realloc(svc->after, sizeof(char*) * (svc->num_after + 1));
char **new;
if (try_unescape(arg, filename, lineno))
return -1;
new = realloc(svc->after, sizeof(char*) * (svc->num_after + 1));
if (new == NULL) {
fprintf(stderr, "%s: %zu: out of memory\n", filename, lineno);
@ -96,7 +117,22 @@ static int svc_after(service_t *svc, char *arg,
static int svc_type(service_t *svc, char *arg,
const char *filename, size_t lineno)
{
int type = svc_type_from_string(arg);
char *extra;
int type;
if (try_unescape(arg, filename, lineno))
return -1;
for (extra = arg; *extra != ' ' && *extra != '\0'; ++extra)
;
if (*extra == ' ') {
*(extra++) = '\0';
} else {
extra = NULL;
}
type = svc_type_from_string(arg);
if (type == -1) {
fprintf(stderr, "%s: %zu: unknown service type '%s'\n",
@ -104,15 +140,51 @@ static int svc_type(service_t *svc, char *arg,
return -1;
}
if (extra != NULL) {
switch (type) {
case SVC_RESPAWN:
if (strncmp(extra, "limit ", 6) != 0)
goto fail_limit;
extra += 6;
svc->rspwn_limit = 0;
if (!isdigit(*extra))
goto fail_limit;
while (isdigit(*extra)) {
svc->rspwn_limit *= 10;
svc->rspwn_limit += *(extra++) - '0';
}
if (*extra != '\0')
goto fail_limit;
break;
default:
fprintf(stderr, "%s: %zu: unexpected extra arguments "
"for type '%s'\n", filename, lineno, arg);
return -1;
}
}
svc->type = type;
free(arg);
return 0;
fail_limit:
fprintf(stderr, "%s: %zu: expected 'limit <value>' after 'respawn'\n",
filename, lineno);
return -1;
}
static int svc_target(service_t *svc, char *arg,
const char *filename, size_t lineno)
{
int target = svc_target_from_string(arg);
int target;
if (try_unescape(arg, filename, lineno))
return -1;
target = svc_target_from_string(arg);
if (target == -1) {
fprintf(stderr, "%s: %zu: unknown service target '%s'\n",
@ -125,33 +197,6 @@ static int svc_target(service_t *svc, char *arg,
return 0;
}
static int svc_rspwn_limit(service_t *svc, char *arg,
const char *filename, size_t lineno)
{
const char *ptr;
svc->rspwn_limit = 0;
if (!isdigit(*arg))
goto fail;
for (ptr = arg; isdigit(*ptr); ++ptr)
svc->rspwn_limit = svc->rspwn_limit * 10 + (*ptr - '0');
if (*ptr != '\0')
goto fail;
free(arg);
return 0;
fail:
fprintf(stderr,
"%s: %zu: expected numeric argument for respawn limit\n",
filename, lineno);
free(arg);
return -1;
}
static const struct {
const char *key;
@ -165,7 +210,6 @@ static const struct {
{ "tty", svc_tty },
{ "before", svc_before },
{ "after", svc_after },
{ "respawn_limit", svc_rspwn_limit },
};
@ -239,36 +283,42 @@ service_t *rdsvc(int dirfd, const char *filename)
goto fail;
}
if (splitkv(line, &key, &value)) {
if (key == NULL) {
fprintf(stderr,
"%s: %zu: expected <key> = <value>\n",
filename, lineno);
} else if (value == NULL) {
fprintf(stderr,
"%s: %zu: expected value after %s\n",
filename, lineno, key);
} else {
fprintf(stderr,
"%s: %zu: unexpected arguments "
"after key-value pair\n",
filename, lineno);
}
goto fail;
}
if (key == NULL) {
if (!strlen(line)) {
free(line);
continue;
}
key = value = line;
while (*value != ' ' && *value != '\0') {
if (!isalpha(*value)) {
fprintf(stderr, "%s: %zu: unexpected '%c' in "
"keyword\n", filename, lineno, *value);
goto fail_line;
}
++value;
}
if (*value == ' ') {
*(value++) = '\0';
} else {
value = NULL;
}
for (i = 0; i < ARRAY_SIZE(svc_params); ++i) {
if (!strcmp(svc_params[i].key, key))
break;
}
if (i >= ARRAY_SIZE(svc_params)) {
fprintf(stderr, "%s: %zu: unknown parameter '%s'\n",
fprintf(stderr, "%s: %zu: unknown keyword '%s'\n",
filename, lineno, key);
goto fail_line;
}
if (value == NULL) {
fprintf(stderr,
"%s: %zu: expected argument after '%s'\n",
filename, lineno, key);
goto fail_line;
}

View file

@ -19,13 +19,6 @@
#include "util.h"
static char *skpspc(char *ptr)
{
while (*ptr == ' ' || *ptr == '\t')
++ptr;
return ptr;
}
static int xdigit(int x)
{
if (isupper(x))
@ -35,107 +28,61 @@ static int xdigit(int x)
return x - '0';
}
static char *parse_str(char *src)
int unescape(char *src)
{
char *dst = src;
int c;
for (;;) {
c = *(src++);
while (*src != '"' && *src != '\0')
*(dst++) = *(src++);
switch (c) {
case '\\':
c = *(src++);
switch (c) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
case '\\': break;
case '"': break;
case 'x':
c = 0;
if (isxdigit(*src))
c = (c << 4) | xdigit(*(src++));
if (isxdigit(*src))
c = (c << 4) | xdigit(*(src++));
break;
case '0':
c = 0;
if (isdigit(*src) && *src < '8')
c = (c << 3) | (*(src++) - '0');
if (isdigit(*src) && *src < '8')
c = (c << 3) | (*(src++) - '0');
if (isdigit(*src) && *src < '8')
c = (c << 3) | (*(src++) - '0');
break;
default:
return NULL;
}
if (*src == '\0')
break;
case '"':
*(dst++) = '\0';
goto out;
++src;
while ((c = *(src++)) != '"') {
if (c == '\0')
return -1;
if (c == '\\') {
c = *(src++);
switch (c) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
case '\\':
case '"':
break;
case 'x':
c = 0;
if (isxdigit(*src))
c = (c<<4) | xdigit(*(src++));
if (isxdigit(*src))
c = (c<<4) | xdigit(*(src++));
break;
case '0':
c = 0;
if (isdigit(*src) && *src < '8')
c = (c<<3) | (*(src++) - '0');
if (isdigit(*src) && *src < '8')
c = (c<<3) | (*(src++) - '0');
if (isdigit(*src) && *src < '8')
c = (c<<3) | (*(src++) - '0');
break;
default:
return -1;
}
}
*(dst++) = c;
}
*(dst++) = c;
}
out:
return src;
}
int splitkv(char *line, char **key, char **value)
{
*key = NULL;
*value = NULL;
line = skpspc(line);
if (*line == '#' || *line == '\0')
return 0;
if (!isalpha(*line))
return -1;
*key = line;
while (isalnum(*line))
++line;
if (*line == ' ' || *line == '\t') {
*(line++) = '\0';
line = skpspc(line);
}
if (*line != '=')
return -1;
*(line++) = '\0';
line = skpspc(line);
if (*line == '"') {
++line;
*value = line;
line = parse_str(line);
} else if (isalnum(*line)) {
*value = line;
while (isalnum(*line) || *line == '.' || *line == '_')
++line;
if (*line != '\0')
*(line++) = '\0';
} else {
return -1;
}
line = skpspc(line);
if (*line != '\0' && *line != '#')
return -1;
*(dst++) = '\0';
return 0;
}

View file

@ -1,6 +1,6 @@
description = "agetty on %0"
exec = "@SBINPATH@/agetty %0 linux"
type = respawn
target = boot
after = sysinit
tty = "/dev/%0"
description agetty on %0
exec "@SBINPATH@/agetty" %0 linux
type respawn
target boot
after sysinit
tty "/dev/%0"

View file

@ -1,6 +1,6 @@
description = "reload hostname"
exec = "@BINPATH@/hostname --file /etc/hostname"
type = wait
target = boot
before = sysinit
after = hwclock
description reload hostname
exec "@BINPATH@/hostname" --file /etc/hostname
type wait
target boot
before sysinit
after hwclock

View file

@ -1,5 +1,5 @@
description = "restore time from RTC"
exec = "@SBINPATH@/hwclock --hctosys --utc"
type = wait
target = boot
before = sysinit
description restore time from RTC
exec "@SBINPATH@/hwclock" --hctosys --utc
type wait
target boot
before sysinit

View file

@ -1,9 +1,9 @@
description = "configure network loopback device"
type = wait
target = boot
before = sysinit
after = hwclock
after = hostname
description configure network loopback device
type wait
target boot
before sysinit
after hwclock
after hostname
exec = "@SBINPATH@/ip addr add 127.0.0.1/8 dev lo brd +"
exec = "@SBINPATH@/ip link set lo up"
exec "@SBINPATH@/ip" addr add 127.0.0.1/8 dev lo brd +
exec "@SBINPATH@/ip" link set lo up

View file

@ -1,7 +1,7 @@
description = "system reboot"
exec = "@SBINPATH@/shutdown -nrf"
type = wait
target = reboot
after = "sync"
after = "sigkill"
after = "sigterm"
description system reboot
exec "@SBINPATH@/shutdown" -nrf
type wait
target reboot
after sync
after sigkill
after sigterm

View file

@ -1,7 +1,7 @@
description = "system shutdown"
exec = "@SBINPATH@/shutdown -npf"
type = wait
target = shutdown
after = "sync"
after = "sigkill"
after = "sigterm"
description system shutdown
exec "@SBINPATH@/shutdown" -npf
type wait
target shutdown
after sync
after sigkill
after sigterm

View file

@ -1,8 +1,8 @@
description = "send SIGKILL to remaining processes"
exec = "@SCRIPTDIR@/killall5 9"
type = wait
target = "%0"
after = "sigterm"
before = "sync"
before = "shutdown"
before = "reboot"
description send SIGKILL to remaining processes
exec "@SCRIPTDIR@/killall5" 9
type wait
target %0
after sigterm
before sync
before shutdown
before reboot

View file

@ -1,9 +1,9 @@
description = "send SIGTERM to all processes"
exec = "@SCRIPTDIR@/killall5 15"
exec = "@BINPATH@/sleep 5"
type = wait
target = "%0"
before = "sigkill"
before = "sync"
before = "reboot"
before = "shutdown"
description send SIGTERM to all processes
exec "@SCRIPTDIR@/killall5" 15
exec "@BINPATH@/sleep" 5
type wait
target %0
before sigkill
before sync
before reboot
before shutdown

View file

@ -1,8 +1,8 @@
description = "sync"
exec = "@BINPATH@/sync"
type = wait
target = "%0"
after = "sigkill"
after = "sigterm"
before = "reboot"
before = "shutdown"
description sync
exec "@BINPATH@/sync"
type wait
target %0
after sigkill
after sigterm
before reboot
before shutdown

View file

@ -1,7 +1,7 @@
description = "configure kernel paramters"
exec = "@SBINPATH@/sysctl --system"
type = wait
target = boot
before = sysinit
after = hwclock
after = hostname
description configure kernel paramters
exec "@SBINPATH@/sysctl" --system
type wait
target boot
before sysinit
after hwclock
after hostname

View file

@ -1,3 +1,3 @@
description = "basic system initialization"
type = once
target = boot
description basic system initialization
type once
target boot