diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-07-07 15:05:37 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-07-07 15:25:55 +0200 |
commit | 418b9be50018303cde79b423d4701b7fd86ddbdc (patch) | |
tree | 9686495c5b3f975cbe8d2e2cfb5abb7e64b21ed3 /src/shared/util.c | |
parent | 037c26d0aeb750ca9c8d605884ea1db7baecfea8 (diff) |
firstboot: add new component to query basic system settings on first boot, or when creating OS images offline
A new tool "systemd-firstboot" can be used either interactively on boot,
where it will query basic locale, timezone, hostname, root password
information and set it. Or it can be used non-interactively from the
command line when prepareing disk images for booting. When used
non-inertactively the tool can either copy settings from the host, or
take settings on the command line.
$ systemd-firstboot --root=/path/to/my/new/root --copy-locale --copy-root-password --hostname=waldi
The tool will be automatically invoked (interactively) now on first boot
if /etc is found unpopulated.
This also creates the infrastructure for generators to be notified via
an environment variable whether they are running on the first boot, or
not.
Diffstat (limited to 'src/shared/util.c')
-rw-r--r-- | src/shared/util.c | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/src/shared/util.c b/src/shared/util.c index d223ecf711..bef87304e6 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1624,7 +1624,7 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { return 0; } -int ask(char *ret, const char *replies, const char *text, ...) { +int ask_char(char *ret, const char *replies, const char *text, ...) { int r; assert(ret); @@ -1672,6 +1672,49 @@ int ask(char *ret, const char *replies, const char *text, ...) { } } +int ask_string(char **ret, const char *text, ...) { + assert(ret); + assert(text); + + for (;;) { + char line[LINE_MAX]; + va_list ap; + + if (on_tty()) + fputs(ANSI_HIGHLIGHT_ON, stdout); + + va_start(ap, text); + vprintf(text, ap); + va_end(ap); + + if (on_tty()) + fputs(ANSI_HIGHLIGHT_OFF, stdout); + + fflush(stdout); + + errno = 0; + if (!fgets(line, sizeof(line), stdin)) + return errno ? -errno : -EIO; + + if (!endswith(line, "\n")) + putchar('\n'); + else { + char *s; + + if (isempty(line)) + continue; + + truncate_nl(line); + s = strdup(line); + if (!s) + return -ENOMEM; + + *ret = s; + return 0; + } + } +} + int reset_terminal_fd(int fd, bool switch_to_text) { struct termios termios; int r = 0; @@ -3752,7 +3795,7 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { return endswith(de->d_name, suffix); } -void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) { +void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[], char *env[]) { pid_t executor_pid; int r; @@ -3783,6 +3826,14 @@ void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); + if (!strv_isempty(env)) { + char **i; + + STRV_FOREACH(i, env) + putenv(*i); + } + + if (!d) { d = _d = opendir(directory); if (!d) { @@ -3807,7 +3858,8 @@ void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv if (!dirent_is_file(de)) continue; - if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) { + path = strjoin(directory, "/", de->d_name, NULL); + if (!path) { log_oom(); _exit(EXIT_FAILURE); } |