X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fload-fragment.c;h=5f5e37397b222c4354be13ef5eb02bc527eb0bb2;hb=a4ddf82766c41627bd94c609bb55983f4b81814f;hp=3ebea4316fc4a86275191fe2e11e9302700ef3bf;hpb=c0120d992ce5ab004d9be5ff6ca15e5fe17f9884;p=elogind.git diff --git a/src/load-fragment.c b/src/load-fragment.c index 3ebea4316..5f5e37397 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -213,6 +213,8 @@ static int config_parse_listen( free(p); return -ENOMEM; } + + path_kill_slashes(p->path); } else { p->type = SOCKET_SOCKET; @@ -450,6 +452,8 @@ static int config_parse_exec( nce->argv = n; nce->path = path; + path_kill_slashes(nce->path); + exec_command_append_list(e, nce); return 0; @@ -1002,6 +1006,143 @@ static int config_parse_mount_flags( return 0; } +static int config_parse_timer( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Timer *t = data; + usec_t u; + int r; + TimerValue *v; + TimerBase b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((b = timer_base_from_string(lvalue)) < 0) { + log_error("[%s:%u] Failed to parse timer base: %s", filename, line, lvalue); + return -EINVAL; + } + + if ((r = parse_usec(rvalue, &u)) < 0) { + log_error("[%s:%u] Failed to parse timer value: %s", filename, line, rvalue); + return r; + } + + if (!(v = new0(TimerValue, 1))) + return -ENOMEM; + + v->base = b; + v->value = u; + + LIST_PREPEND(TimerValue, value, t->values, v); + + return 0; +} + +static int config_parse_timer_unit( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Timer *t = data; + int r; + + if (endswith(rvalue, ".timer")) { + log_error("[%s:%u] Unit cannot be of type timer: %s", filename, line, rvalue); + return -EINVAL; + } + + if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, &t->unit)) < 0) { + log_error("[%s:%u] Failed to load unit: %s", filename, line, rvalue); + return r; + } + + return 0; +} + +static int config_parse_path_spec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Path *p = data; + PathSpec *s; + PathType b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((b = path_type_from_string(lvalue)) < 0) { + log_error("[%s:%u] Failed to parse path type: %s", filename, line, lvalue); + return -EINVAL; + } + + if (!path_is_absolute(rvalue)) { + log_error("[%s:%u] Path is not absolute: %s", filename, line, rvalue); + return -EINVAL; + } + + if (!(s = new0(PathSpec, 1))) + return -ENOMEM; + + if (!(s->path = strdup(rvalue))) { + free(s); + return -ENOMEM; + } + + path_kill_slashes(s->path); + + s->type = b; + s->inotify_fd = -1; + + LIST_PREPEND(PathSpec, spec, p->specs, s); + + return 0; +} + +static int config_parse_path_unit( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Path *t = data; + int r; + + if (endswith(rvalue, ".path")) { + log_error("[%s:%u] Unit cannot be of type path: %s", filename, line, rvalue); + return -EINVAL; + } + + if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, &t->unit)) < 0) { + log_error("[%s:%u] Failed to load unit: %s", filename, line, rvalue); + return r; + } + + return 0; +} + #define FOLLOW_MAX 8 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { @@ -1161,6 +1302,8 @@ static void dump_items(FILE *f, const ConfigItem *items) { { config_parse_path_strv, "PATH [...]" }, { config_parse_mount_flags, "MOUNTFLAG [...]" }, { config_parse_description, "DESCRIPTION" }, + { config_parse_timer, "TIMER" }, + { config_parse_timer_unit, "NAME" }, }; assert(f); @@ -1201,7 +1344,8 @@ static int load_from_path(Unit *u, const char *path) { [UNIT_MOUNT] = "Mount", [UNIT_AUTOMOUNT] = "Automount", [UNIT_SNAPSHOT] = "Snapshot", - [UNIT_SWAP] = "Swap" + [UNIT_SWAP] = "Swap", + [UNIT_PATH] = "Path" }; #define EXEC_CONTEXT_CONFIG_ITEMS(context, section) \ @@ -1222,7 +1366,7 @@ static int load_from_path(Unit *u, const char *path) { { "Environment", config_parse_strv, &(context).environment, section }, \ { "StandardInput", config_parse_input, &(context).std_input, section }, \ { "StandardOutput", config_parse_output, &(context).std_output, section }, \ - { "StandardError", config_parse_output, &(context).std_output, section }, \ + { "StandardError", config_parse_output, &(context).std_error, section }, \ { "TTYPath", config_parse_path, &(context).tty_path, section }, \ { "SyslogIdentifier", config_parse_string, &(context).syslog_identifier, section }, \ { "SyslogFacility", config_parse_facility, &(context).syslog_priority, section }, \ @@ -1268,6 +1412,7 @@ static int load_from_path(Unit *u, const char *path) { { "After", config_parse_deps, UINT_TO_PTR(UNIT_AFTER), "Unit" }, { "RecursiveStop", config_parse_bool, &u->meta.recursive_stop, "Unit" }, { "StopWhenUnneeded", config_parse_bool, &u->meta.stop_when_unneeded, "Unit" }, + { "OnlyByDependency", config_parse_bool, &u->meta.only_by_dependency, "Unit" }, { "PIDFile", config_parse_path, &u->service.pid_file, "Service" }, { "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" }, @@ -1317,8 +1462,20 @@ static int load_from_path(Unit *u, const char *path) { { "Where", config_parse_path, &u->automount.where, "Automount" }, - { "What", config_parse_path, &u->swap.parameters_fragment.what, "Swap" }, - { "Priority", config_parse_int, &u->swap.parameters_fragment.priority, "Swap" }, + { "What", config_parse_path, &u->swap.parameters_fragment.what, "Swap" }, + { "Priority", config_parse_int, &u->swap.parameters_fragment.priority, "Swap" }, + + { "OnActive", config_parse_timer, &u->timer, "Timer" }, + { "OnBoot", config_parse_timer, &u->timer, "Timer" }, + { "OnStartup", config_parse_timer, &u->timer, "Timer" }, + { "OnUnitActive", config_parse_timer, &u->timer, "Timer" }, + { "OnUnitInactive", config_parse_timer, &u->timer, "Timer" }, + { "Unit", config_parse_timer_unit, &u->timer, "Timer" }, + + { "PathExists", config_parse_path_spec, &u->path, "Path" }, + { "PathChanged", config_parse_path_spec, &u->path, "Path" }, + { "DirectoryNotEmpty", config_parse_path_spec, &u->path, "Path" }, + { "Unit", config_parse_path_unit, &u->path, "Path" }, { NULL, NULL, NULL, NULL } };