summaryrefslogtreecommitdiff
path: root/src/shared/util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-07-07 15:05:37 +0200
committerLennart Poettering <lennart@poettering.net>2014-07-07 15:25:55 +0200
commit418b9be50018303cde79b423d4701b7fd86ddbdc (patch)
tree9686495c5b3f975cbe8d2e2cfb5abb7e64b21ed3 /src/shared/util.c
parent037c26d0aeb750ca9c8d605884ea1db7baecfea8 (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.c58
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);
}