]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/firstboot/firstboot.c
Merge pull request #8817 from yuwata/cleanup-nsflags
[thirdparty/systemd.git] / src / firstboot / firstboot.c
index 1435880fab8e74e6b792bf3c3db92e70c9365485..7895e3832aa0516f1e92ac1b538fecaafcd6a456 100644 (file)
@@ -3,26 +3,27 @@
   This file is part of systemd.
 
   Copyright 2014 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
 #include <fcntl.h>
 #include <getopt.h>
-#include <shadow.h>
 #include <unistd.h>
 
+#ifdef HAVE_CRYPT_H
+/* libxcrypt is a replacement for glibc's libcrypt, and libcrypt might be
+ * removed from glibc at some point. As part of the removal, defines for
+ * crypt(3) are dropped from unistd.h, and we must include crypt.h instead.
+ *
+ * Newer versions of glibc (v2.0+) already ship crypt.h with a definition
+ * of crypt(3) as well, so we simply include it if it is present.  MariaDB,
+ * MySQL, PostgreSQL, Perl and some other wide-spread packages do it the
+ * same way since ages without any problems.
+ */
+#  include <crypt.h>
+#endif
+
+#include "sd-id128.h"
+
 #include "alloc-util.h"
 #include "ask-password-api.h"
 #include "copy.h"
@@ -109,13 +110,13 @@ static void print_welcome(void) {
 }
 
 static int show_menu(char **x, unsigned n_columns, unsigned width, unsigned percentage) {
-        unsigned n, per_column, i, j;
         unsigned break_lines, break_modulo;
+        size_t n, per_column, i, j;
 
         assert(n_columns > 0);
 
         n = strv_length(x);
-        per_column = (n + n_columns - 1) / n_columns;
+        per_column = DIV_ROUND_UP(n, n_columns);
 
         break_lines = lines();
         if (break_lines > 2)
@@ -139,7 +140,7 @@ static int show_menu(char **x, unsigned n_columns, unsigned width, unsigned perc
                         if (!e)
                                 return log_oom();
 
-                        printf("%4u) %-*s", j * per_column + i + 1, width, e);
+                        printf("%4zu) %-*s", j * per_column + i + 1, width, e);
                 }
 
                 putchar('\n');
@@ -314,14 +315,8 @@ static int prompt_keymap(void) {
 
         putchar('\n');
 
-        r = prompt_loop("Please enter system keymap name or number", kmaps, keymap_is_valid, &arg_keymap);
-        if (r < 0)
-                return r;
-
-        if (isempty(arg_keymap))
-                return 0;
-
-        return 0;
+        return prompt_loop("Please enter system keymap name or number",
+                           kmaps, keymap_is_valid, &arg_keymap);
 }
 
 static int process_keymap(void) {
@@ -352,13 +347,15 @@ static int process_keymap(void) {
         if (r < 0)
                 return r;
 
-        if (!isempty(arg_keymap))
-                keymap = STRV_MAKE(strjoina("KEYMAP=", arg_keymap));
-
-        if (!keymap)
+        if (isempty(arg_keymap))
                 return 0;
 
-        mkdir_parents(etc_vconsoleconf, 0755);
+        keymap = STRV_MAKE(strjoina("KEYMAP=", arg_keymap));
+
+        r = mkdir_parents(etc_vconsoleconf, 0755);
+        if (r < 0)
+                return log_error_errno(r, "Failed to create the parent directory of %s: %m", etc_vconsoleconf);
+
         r = write_env_file(etc_vconsoleconf, keymap);
         if (r < 0)
                 return log_error_errno(r, "Failed to write %s: %m", etc_vconsoleconf);
@@ -367,6 +364,10 @@ static int process_keymap(void) {
         return 0;
 }
 
+static bool timezone_is_valid_log_error(const char *name) {
+        return timezone_is_valid(name, LOG_ERR);
+}
+
 static int prompt_timezone(void) {
         _cleanup_strv_free_ char **zones = NULL;
         int r;
@@ -390,7 +391,7 @@ static int prompt_timezone(void) {
 
         putchar('\n');
 
-        r = prompt_loop("Please enter timezone name or number", zones, timezone_is_valid, &arg_timezone);
+        r = prompt_loop("Please enter timezone name or number", zones, timezone_is_valid_log_error, &arg_timezone);
         if (r < 0)
                 return r;
 
@@ -547,7 +548,7 @@ static int prompt_root_password(void) {
         for (;;) {
                 _cleanup_string_free_erase_ char *a = NULL, *b = NULL;
 
-                r = ask_password_tty(msg1, NULL, 0, 0, NULL, &a);
+                r = ask_password_tty(-1, msg1, NULL, 0, 0, NULL, &a);
                 if (r < 0)
                         return log_error_errno(r, "Failed to query root password: %m");
 
@@ -556,7 +557,7 @@ static int prompt_root_password(void) {
                         break;
                 }
 
-                r = ask_password_tty(msg2, NULL, 0, 0, NULL, &b);
+                r = ask_password_tty(-1, msg2, NULL, 0, 0, NULL, &b);
                 if (r < 0)
                         return log_error_errno(r, "Failed to query root password: %m");
 
@@ -565,8 +566,7 @@ static int prompt_root_password(void) {
                         continue;
                 }
 
-                arg_root_password = a;
-                a = NULL;
+                arg_root_password = TAKE_PTR(a);
                 break;
         }
 
@@ -575,6 +575,8 @@ static int prompt_root_password(void) {
 
 static int write_root_shadow(const char *path, const struct spwd *p) {
         _cleanup_fclose_ FILE *f = NULL;
+        int r;
+
         assert(path);
         assert(p);
 
@@ -583,9 +585,9 @@ static int write_root_shadow(const char *path, const struct spwd *p) {
         if (!f)
                 return -errno;
 
-        errno = 0;
-        if (putspent(p, f) != 0)
-                return errno > 0 ? -errno : -EIO;
+        r = putspent_sane(p, f);
+        if (r < 0)
+                return r;
 
         return fflush_sync_and_check(f);
 }
@@ -829,7 +831,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_TIMEZONE:
-                        if (!timezone_is_valid(optarg)) {
+                        if (!timezone_is_valid(optarg, LOG_ERR)) {
                                 log_error("Timezone %s is not valid.", optarg);
                                 return -EINVAL;
                         }