LCOV - code coverage report
Current view: top level - firstboot - firstboot.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 507 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 28 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 631 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <fcntl.h>
       4                 :            : #include <getopt.h>
       5                 :            : #include <unistd.h>
       6                 :            : 
       7                 :            : #if HAVE_CRYPT_H
       8                 :            : /* libxcrypt is a replacement for glibc's libcrypt, and libcrypt might be
       9                 :            :  * removed from glibc at some point. As part of the removal, defines for
      10                 :            :  * crypt(3) are dropped from unistd.h, and we must include crypt.h instead.
      11                 :            :  *
      12                 :            :  * Newer versions of glibc (v2.0+) already ship crypt.h with a definition
      13                 :            :  * of crypt(3) as well, so we simply include it if it is present.  MariaDB,
      14                 :            :  * MySQL, PostgreSQL, Perl and some other wide-spread packages do it the
      15                 :            :  * same way since ages without any problems.
      16                 :            :  */
      17                 :            : #  include <crypt.h>
      18                 :            : #endif
      19                 :            : 
      20                 :            : #include "sd-id128.h"
      21                 :            : 
      22                 :            : #include "alloc-util.h"
      23                 :            : #include "ask-password-api.h"
      24                 :            : #include "copy.h"
      25                 :            : #include "env-file.h"
      26                 :            : #include "fd-util.h"
      27                 :            : #include "fileio.h"
      28                 :            : #include "fs-util.h"
      29                 :            : #include "hostname-util.h"
      30                 :            : #include "kbd-util.h"
      31                 :            : #include "locale-util.h"
      32                 :            : #include "main-func.h"
      33                 :            : #include "memory-util.h"
      34                 :            : #include "mkdir.h"
      35                 :            : #include "os-util.h"
      36                 :            : #include "parse-util.h"
      37                 :            : #include "path-util.h"
      38                 :            : #include "pretty-print.h"
      39                 :            : #include "proc-cmdline.h"
      40                 :            : #include "random-util.h"
      41                 :            : #include "string-util.h"
      42                 :            : #include "strv.h"
      43                 :            : #include "terminal-util.h"
      44                 :            : #include "time-util.h"
      45                 :            : #include "umask-util.h"
      46                 :            : #include "user-util.h"
      47                 :            : 
      48                 :            : static char *arg_root = NULL;
      49                 :            : static char *arg_locale = NULL;  /* $LANG */
      50                 :            : static char *arg_keymap = NULL;
      51                 :            : static char *arg_locale_messages = NULL; /* $LC_MESSAGES */
      52                 :            : static char *arg_timezone = NULL;
      53                 :            : static char *arg_hostname = NULL;
      54                 :            : static sd_id128_t arg_machine_id = {};
      55                 :            : static char *arg_root_password = NULL;
      56                 :            : static bool arg_prompt_locale = false;
      57                 :            : static bool arg_prompt_keymap = false;
      58                 :            : static bool arg_prompt_timezone = false;
      59                 :            : static bool arg_prompt_hostname = false;
      60                 :            : static bool arg_prompt_root_password = false;
      61                 :            : static bool arg_copy_locale = false;
      62                 :            : static bool arg_copy_keymap = false;
      63                 :            : static bool arg_copy_timezone = false;
      64                 :            : static bool arg_copy_root_password = false;
      65                 :            : 
      66                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
      67                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_locale, freep);
      68                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_locale_messages, freep);
      69                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_keymap, freep);
      70                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_timezone, freep);
      71                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_hostname, freep);
      72                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_root_password, erase_and_freep);
      73                 :            : 
      74                 :          0 : static bool press_any_key(void) {
      75                 :          0 :         char k = 0;
      76                 :          0 :         bool need_nl = true;
      77                 :            : 
      78                 :          0 :         printf("-- Press any key to proceed --");
      79                 :          0 :         fflush(stdout);
      80                 :            : 
      81                 :          0 :         (void) read_one_char(stdin, &k, USEC_INFINITY, &need_nl);
      82                 :            : 
      83         [ #  # ]:          0 :         if (need_nl)
      84                 :          0 :                 putchar('\n');
      85                 :            : 
      86                 :          0 :         return k != 'q';
      87                 :            : }
      88                 :            : 
      89                 :          0 : static void print_welcome(void) {
      90   [ #  #  #  # ]:          0 :         _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
      91                 :            :         static bool done = false;
      92                 :            :         const char *pn;
      93                 :            :         int r;
      94                 :            : 
      95         [ #  # ]:          0 :         if (done)
      96                 :          0 :                 return;
      97                 :            : 
      98                 :          0 :         r = parse_os_release(
      99                 :            :                         arg_root,
     100                 :            :                         "PRETTY_NAME", &pretty_name,
     101                 :            :                         "ANSI_COLOR", &ansi_color,
     102                 :            :                         NULL);
     103         [ #  # ]:          0 :         if (r < 0)
     104   [ #  #  #  # ]:          0 :                 log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
     105                 :            :                                "Failed to read os-release file, ignoring: %m");
     106                 :            : 
     107         [ #  # ]:          0 :         pn = isempty(pretty_name) ? "Linux" : pretty_name;
     108                 :            : 
     109         [ #  # ]:          0 :         if (colors_enabled())
     110                 :          0 :                 printf("\nWelcome to your new installation of \x1B[%sm%s\x1B[0m!\n", ansi_color, pn);
     111                 :            :         else
     112                 :          0 :                 printf("\nWelcome to your new installation of %s!\n", pn);
     113                 :            : 
     114                 :          0 :         printf("\nPlease configure your system!\n\n");
     115                 :            : 
     116                 :          0 :         press_any_key();
     117                 :            : 
     118                 :          0 :         done = true;
     119                 :            : }
     120                 :            : 
     121                 :          0 : static int show_menu(char **x, unsigned n_columns, unsigned width, unsigned percentage) {
     122                 :            :         unsigned break_lines, break_modulo;
     123                 :            :         size_t n, per_column, i, j;
     124                 :            : 
     125         [ #  # ]:          0 :         assert(n_columns > 0);
     126                 :            : 
     127                 :          0 :         n = strv_length(x);
     128                 :          0 :         per_column = DIV_ROUND_UP(n, n_columns);
     129                 :            : 
     130                 :          0 :         break_lines = lines();
     131         [ #  # ]:          0 :         if (break_lines > 2)
     132                 :          0 :                 break_lines--;
     133                 :            : 
     134                 :            :         /* The first page gets two extra lines, since we want to show
     135                 :            :          * a title */
     136                 :          0 :         break_modulo = break_lines;
     137         [ #  # ]:          0 :         if (break_modulo > 3)
     138                 :          0 :                 break_modulo -= 3;
     139                 :            : 
     140         [ #  # ]:          0 :         for (i = 0; i < per_column; i++) {
     141                 :            : 
     142         [ #  # ]:          0 :                 for (j = 0; j < n_columns; j ++) {
     143      [ #  #  # ]:          0 :                         _cleanup_free_ char *e = NULL;
     144                 :            : 
     145         [ #  # ]:          0 :                         if (j * per_column + i >= n)
     146                 :          0 :                                 break;
     147                 :            : 
     148                 :          0 :                         e = ellipsize(x[j * per_column + i], width, percentage);
     149         [ #  # ]:          0 :                         if (!e)
     150                 :          0 :                                 return log_oom();
     151                 :            : 
     152                 :          0 :                         printf("%4zu) %-*s", j * per_column + i + 1, width, e);
     153                 :            :                 }
     154                 :            : 
     155                 :          0 :                 putchar('\n');
     156                 :            : 
     157                 :            :                 /* on the first screen we reserve 2 extra lines for the title */
     158         [ #  # ]:          0 :                 if (i % break_lines == break_modulo) {
     159         [ #  # ]:          0 :                         if (!press_any_key())
     160                 :          0 :                                 return 0;
     161                 :            :                 }
     162                 :            :         }
     163                 :            : 
     164                 :          0 :         return 0;
     165                 :            : }
     166                 :            : 
     167                 :          0 : static int prompt_loop(const char *text, char **l, unsigned percentage, bool (*is_valid)(const char *name), char **ret) {
     168                 :            :         int r;
     169                 :            : 
     170         [ #  # ]:          0 :         assert(text);
     171         [ #  # ]:          0 :         assert(is_valid);
     172         [ #  # ]:          0 :         assert(ret);
     173                 :            : 
     174                 :          0 :         for (;;) {
     175         [ #  # ]:          0 :                 _cleanup_free_ char *p = NULL;
     176                 :            :                 unsigned u;
     177                 :            : 
     178                 :          0 :                 r = ask_string(&p, "%s %s (empty to skip, \"list\" to list options): ",
     179                 :            :                                special_glyph(SPECIAL_GLYPH_TRIANGULAR_BULLET), text);
     180         [ #  # ]:          0 :                 if (r < 0)
     181         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to query user: %m");
     182                 :            : 
     183         [ #  # ]:          0 :                 if (isempty(p)) {
     184         [ #  # ]:          0 :                         log_warning("No data entered, skipping.");
     185                 :          0 :                         return 0;
     186                 :            :                 }
     187                 :            : 
     188         [ #  # ]:          0 :                 if (streq(p, "list")) {
     189                 :          0 :                         r = show_menu(l, 3, 22, percentage);
     190         [ #  # ]:          0 :                         if (r < 0)
     191                 :          0 :                                 return r;
     192                 :            : 
     193                 :          0 :                         putchar('\n');
     194                 :          0 :                         continue;
     195                 :            :                 };
     196                 :            : 
     197                 :          0 :                 r = safe_atou(p, &u);
     198         [ #  # ]:          0 :                 if (r >= 0) {
     199   [ #  #  #  # ]:          0 :                         if (u <= 0 || u > strv_length(l)) {
     200         [ #  # ]:          0 :                                 log_error("Specified entry number out of range.");
     201                 :          0 :                                 continue;
     202                 :            :                         }
     203                 :            : 
     204         [ #  # ]:          0 :                         log_info("Selected '%s'.", l[u-1]);
     205         [ #  # ]:          0 :                         if (free_and_strdup(ret, l[u-1]) < 0)
     206                 :          0 :                                 return log_oom();
     207                 :            : 
     208                 :          0 :                         return 0;
     209                 :            :                 }
     210                 :            : 
     211         [ #  # ]:          0 :                 if (!is_valid(p)) {
     212         [ #  # ]:          0 :                         log_error("Entered data invalid.");
     213                 :          0 :                         continue;
     214                 :            :                 }
     215                 :            : 
     216                 :          0 :                 return free_and_replace(*ret, p);
     217                 :            :         }
     218                 :            : }
     219                 :            : 
     220                 :          0 : static int prompt_locale(void) {
     221                 :          0 :         _cleanup_strv_free_ char **locales = NULL;
     222                 :            :         int r;
     223                 :            : 
     224   [ #  #  #  # ]:          0 :         if (arg_locale || arg_locale_messages)
     225                 :          0 :                 return 0;
     226                 :            : 
     227         [ #  # ]:          0 :         if (!arg_prompt_locale)
     228                 :          0 :                 return 0;
     229                 :            : 
     230                 :          0 :         r = get_locales(&locales);
     231         [ #  # ]:          0 :         if (r < 0)
     232         [ #  # ]:          0 :                 return log_error_errno(r, "Cannot query locales list: %m");
     233                 :            : 
     234         [ #  # ]:          0 :         if (strv_isempty(locales))
     235         [ #  # ]:          0 :                 log_debug("No locales found, skipping locale selection.");
     236         [ #  # ]:          0 :         else if (strv_length(locales) == 1) {
     237                 :            : 
     238         [ #  # ]:          0 :                 if (streq(locales[0], SYSTEMD_DEFAULT_LOCALE))
     239         [ #  # ]:          0 :                         log_debug("Only installed locale is default locale anyway, not setting locale explicitly.");
     240                 :            :                 else {
     241         [ #  # ]:          0 :                         log_debug("Only a single locale available (%s), selecting it as default.", locales[0]);
     242                 :            : 
     243                 :          0 :                         arg_locale = strdup(locales[0]);
     244         [ #  # ]:          0 :                         if (!arg_locale)
     245                 :          0 :                                 return log_oom();
     246                 :            : 
     247                 :            :                         /* Not setting arg_locale_message here, since it defaults to LANG anyway */
     248                 :            :                 }
     249                 :            :         } else {
     250                 :          0 :                 print_welcome();
     251                 :            : 
     252                 :          0 :                 r = prompt_loop("Please enter system locale name or number",
     253                 :            :                                 locales, 60, locale_is_valid, &arg_locale);
     254         [ #  # ]:          0 :                 if (r < 0)
     255                 :          0 :                         return r;
     256                 :            : 
     257         [ #  # ]:          0 :                 if (isempty(arg_locale))
     258                 :          0 :                         return 0;
     259                 :            : 
     260                 :          0 :                 r = prompt_loop("Please enter system message locale name or number",
     261                 :            :                                 locales, 60, locale_is_valid, &arg_locale_messages);
     262         [ #  # ]:          0 :                 if (r < 0)
     263                 :          0 :                         return r;
     264                 :            : 
     265                 :            :                 /* Suppress the messages setting if it's the same as the main locale anyway */
     266         [ #  # ]:          0 :                 if (streq_ptr(arg_locale, arg_locale_messages))
     267                 :          0 :                         arg_locale_messages = mfree(arg_locale_messages);
     268                 :            :         }
     269                 :            : 
     270                 :          0 :         return 0;
     271                 :            : }
     272                 :            : 
     273                 :          0 : static int process_locale(void) {
     274                 :            :         const char *etc_localeconf;
     275                 :            :         char* locales[3];
     276                 :          0 :         unsigned i = 0;
     277                 :            :         int r;
     278                 :            : 
     279   [ #  #  #  #  :          0 :         etc_localeconf = prefix_roota(arg_root, "/etc/locale.conf");
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     280         [ #  # ]:          0 :         if (laccess(etc_localeconf, F_OK) >= 0)
     281                 :          0 :                 return 0;
     282                 :            : 
     283   [ #  #  #  # ]:          0 :         if (arg_copy_locale && arg_root) {
     284                 :            : 
     285                 :          0 :                 (void) mkdir_parents(etc_localeconf, 0755);
     286                 :          0 :                 r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, 0, 0, COPY_REFLINK);
     287         [ #  # ]:          0 :                 if (r != -ENOENT) {
     288         [ #  # ]:          0 :                         if (r < 0)
     289         [ #  # ]:          0 :                                 return log_error_errno(r, "Failed to copy %s: %m", etc_localeconf);
     290                 :            : 
     291         [ #  # ]:          0 :                         log_info("%s copied.", etc_localeconf);
     292                 :          0 :                         return 0;
     293                 :            :                 }
     294                 :            :         }
     295                 :            : 
     296                 :          0 :         r = prompt_locale();
     297         [ #  # ]:          0 :         if (r < 0)
     298                 :          0 :                 return r;
     299                 :            : 
     300         [ #  # ]:          0 :         if (!isempty(arg_locale))
     301   [ #  #  #  #  :          0 :                 locales[i++] = strjoina("LANG=", arg_locale);
          #  #  #  #  #  
                #  #  # ]
     302   [ #  #  #  # ]:          0 :         if (!isempty(arg_locale_messages) && !streq(arg_locale_messages, arg_locale))
     303   [ #  #  #  #  :          0 :                 locales[i++] = strjoina("LC_MESSAGES=", arg_locale_messages);
          #  #  #  #  #  
                #  #  # ]
     304                 :            : 
     305         [ #  # ]:          0 :         if (i == 0)
     306                 :          0 :                 return 0;
     307                 :            : 
     308                 :          0 :         locales[i] = NULL;
     309                 :            : 
     310                 :          0 :         (void) mkdir_parents(etc_localeconf, 0755);
     311                 :          0 :         r = write_env_file(etc_localeconf, locales);
     312         [ #  # ]:          0 :         if (r < 0)
     313         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write %s: %m", etc_localeconf);
     314                 :            : 
     315         [ #  # ]:          0 :         log_info("%s written.", etc_localeconf);
     316                 :          0 :         return 0;
     317                 :            : }
     318                 :            : 
     319                 :          0 : static int prompt_keymap(void) {
     320                 :          0 :         _cleanup_strv_free_ char **kmaps = NULL;
     321                 :            :         int r;
     322                 :            : 
     323         [ #  # ]:          0 :         if (arg_keymap)
     324                 :          0 :                 return 0;
     325                 :            : 
     326         [ #  # ]:          0 :         if (!arg_prompt_keymap)
     327                 :          0 :                 return 0;
     328                 :            : 
     329                 :          0 :         r = get_keymaps(&kmaps);
     330         [ #  # ]:          0 :         if (r == -ENOENT) /* no keymaps installed */
     331                 :          0 :                 return r;
     332         [ #  # ]:          0 :         if (r < 0)
     333         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to read keymaps: %m");
     334                 :            : 
     335                 :          0 :         print_welcome();
     336                 :            : 
     337                 :          0 :         return prompt_loop("Please enter system keymap name or number",
     338                 :            :                            kmaps, 60, keymap_is_valid, &arg_keymap);
     339                 :            : }
     340                 :            : 
     341                 :          0 : static int process_keymap(void) {
     342                 :            :         const char *etc_vconsoleconf;
     343                 :            :         char **keymap;
     344                 :            :         int r;
     345                 :            : 
     346   [ #  #  #  #  :          0 :         etc_vconsoleconf = prefix_roota(arg_root, "/etc/vconsole.conf");
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     347         [ #  # ]:          0 :         if (laccess(etc_vconsoleconf, F_OK) >= 0)
     348                 :          0 :                 return 0;
     349                 :            : 
     350   [ #  #  #  # ]:          0 :         if (arg_copy_keymap && arg_root) {
     351                 :            : 
     352                 :          0 :                 (void) mkdir_parents(etc_vconsoleconf, 0755);
     353                 :          0 :                 r = copy_file("/etc/vconsole.conf", etc_vconsoleconf, 0, 0644, 0, 0, COPY_REFLINK);
     354         [ #  # ]:          0 :                 if (r != -ENOENT) {
     355         [ #  # ]:          0 :                         if (r < 0)
     356         [ #  # ]:          0 :                                 return log_error_errno(r, "Failed to copy %s: %m", etc_vconsoleconf);
     357                 :            : 
     358         [ #  # ]:          0 :                         log_info("%s copied.", etc_vconsoleconf);
     359                 :          0 :                         return 0;
     360                 :            :                 }
     361                 :            :         }
     362                 :            : 
     363                 :          0 :         r = prompt_keymap();
     364         [ #  # ]:          0 :         if (r == -ENOENT)
     365                 :          0 :                 return 0; /* don't fail if no keymaps are installed */
     366         [ #  # ]:          0 :         if (r < 0)
     367                 :          0 :                 return r;
     368                 :            : 
     369         [ #  # ]:          0 :         if (isempty(arg_keymap))
     370                 :          0 :                 return 0;
     371                 :            : 
     372   [ #  #  #  #  :          0 :         keymap = STRV_MAKE(strjoina("KEYMAP=", arg_keymap));
          #  #  #  #  #  
                #  #  # ]
     373                 :            : 
     374                 :          0 :         r = mkdir_parents(etc_vconsoleconf, 0755);
     375         [ #  # ]:          0 :         if (r < 0)
     376         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to create the parent directory of %s: %m", etc_vconsoleconf);
     377                 :            : 
     378                 :          0 :         r = write_env_file(etc_vconsoleconf, keymap);
     379         [ #  # ]:          0 :         if (r < 0)
     380         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write %s: %m", etc_vconsoleconf);
     381                 :            : 
     382         [ #  # ]:          0 :         log_info("%s written.", etc_vconsoleconf);
     383                 :          0 :         return 0;
     384                 :            : }
     385                 :            : 
     386                 :          0 : static bool timezone_is_valid_log_error(const char *name) {
     387                 :          0 :         return timezone_is_valid(name, LOG_ERR);
     388                 :            : }
     389                 :            : 
     390                 :          0 : static int prompt_timezone(void) {
     391                 :          0 :         _cleanup_strv_free_ char **zones = NULL;
     392                 :            :         int r;
     393                 :            : 
     394         [ #  # ]:          0 :         if (arg_timezone)
     395                 :          0 :                 return 0;
     396                 :            : 
     397         [ #  # ]:          0 :         if (!arg_prompt_timezone)
     398                 :          0 :                 return 0;
     399                 :            : 
     400                 :          0 :         r = get_timezones(&zones);
     401         [ #  # ]:          0 :         if (r < 0)
     402         [ #  # ]:          0 :                 return log_error_errno(r, "Cannot query timezone list: %m");
     403                 :            : 
     404                 :          0 :         print_welcome();
     405                 :            : 
     406                 :          0 :         r = prompt_loop("Please enter timezone name or number",
     407                 :            :                         zones, 30, timezone_is_valid_log_error, &arg_timezone);
     408         [ #  # ]:          0 :         if (r < 0)
     409                 :          0 :                 return r;
     410                 :            : 
     411                 :          0 :         return 0;
     412                 :            : }
     413                 :            : 
     414                 :          0 : static int process_timezone(void) {
     415                 :            :         const char *etc_localtime, *e;
     416                 :            :         int r;
     417                 :            : 
     418   [ #  #  #  #  :          0 :         etc_localtime = prefix_roota(arg_root, "/etc/localtime");
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     419         [ #  # ]:          0 :         if (laccess(etc_localtime, F_OK) >= 0)
     420                 :          0 :                 return 0;
     421                 :            : 
     422   [ #  #  #  # ]:          0 :         if (arg_copy_timezone && arg_root) {
     423         [ #  # ]:          0 :                 _cleanup_free_ char *p = NULL;
     424                 :            : 
     425                 :          0 :                 r = readlink_malloc("/etc/localtime", &p);
     426         [ #  # ]:          0 :                 if (r != -ENOENT) {
     427         [ #  # ]:          0 :                         if (r < 0)
     428         [ #  # ]:          0 :                                 return log_error_errno(r, "Failed to read host timezone: %m");
     429                 :            : 
     430                 :          0 :                         (void) mkdir_parents(etc_localtime, 0755);
     431         [ #  # ]:          0 :                         if (symlink(p, etc_localtime) < 0)
     432         [ #  # ]:          0 :                                 return log_error_errno(errno, "Failed to create %s symlink: %m", etc_localtime);
     433                 :            : 
     434         [ #  # ]:          0 :                         log_info("%s copied.", etc_localtime);
     435                 :          0 :                         return 0;
     436                 :            :                 }
     437                 :            :         }
     438                 :            : 
     439                 :          0 :         r = prompt_timezone();
     440         [ #  # ]:          0 :         if (r < 0)
     441                 :          0 :                 return r;
     442                 :            : 
     443         [ #  # ]:          0 :         if (isempty(arg_timezone))
     444                 :          0 :                 return 0;
     445                 :            : 
     446   [ #  #  #  #  :          0 :         e = strjoina("../usr/share/zoneinfo/", arg_timezone);
          #  #  #  #  #  
                #  #  # ]
     447                 :            : 
     448                 :          0 :         (void) mkdir_parents(etc_localtime, 0755);
     449         [ #  # ]:          0 :         if (symlink(e, etc_localtime) < 0)
     450         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to create %s symlink: %m", etc_localtime);
     451                 :            : 
     452         [ #  # ]:          0 :         log_info("%s written", etc_localtime);
     453                 :          0 :         return 0;
     454                 :            : }
     455                 :            : 
     456                 :          0 : static int prompt_hostname(void) {
     457                 :            :         int r;
     458                 :            : 
     459         [ #  # ]:          0 :         if (arg_hostname)
     460                 :          0 :                 return 0;
     461                 :            : 
     462         [ #  # ]:          0 :         if (!arg_prompt_hostname)
     463                 :          0 :                 return 0;
     464                 :            : 
     465                 :          0 :         print_welcome();
     466                 :          0 :         putchar('\n');
     467                 :            : 
     468                 :          0 :         for (;;) {
     469      [ #  #  # ]:          0 :                 _cleanup_free_ char *h = NULL;
     470                 :            : 
     471                 :          0 :                 r = ask_string(&h, "%s Please enter hostname for new system (empty to skip): ", special_glyph(SPECIAL_GLYPH_TRIANGULAR_BULLET));
     472         [ #  # ]:          0 :                 if (r < 0)
     473         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to query hostname: %m");
     474                 :            : 
     475         [ #  # ]:          0 :                 if (isempty(h)) {
     476         [ #  # ]:          0 :                         log_warning("No hostname entered, skipping.");
     477                 :          0 :                         break;
     478                 :            :                 }
     479                 :            : 
     480         [ #  # ]:          0 :                 if (!hostname_is_valid(h, true)) {
     481         [ #  # ]:          0 :                         log_error("Specified hostname invalid.");
     482                 :          0 :                         continue;
     483                 :            :                 }
     484                 :            : 
     485                 :            :                 /* Get rid of the trailing dot that we allow, but don't want to see */
     486                 :          0 :                 arg_hostname = hostname_cleanup(h);
     487                 :          0 :                 h = NULL;
     488                 :          0 :                 break;
     489                 :            :         }
     490                 :            : 
     491                 :          0 :         return 0;
     492                 :            : }
     493                 :            : 
     494                 :          0 : static int process_hostname(void) {
     495                 :            :         const char *etc_hostname;
     496                 :            :         int r;
     497                 :            : 
     498   [ #  #  #  #  :          0 :         etc_hostname = prefix_roota(arg_root, "/etc/hostname");
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     499         [ #  # ]:          0 :         if (laccess(etc_hostname, F_OK) >= 0)
     500                 :          0 :                 return 0;
     501                 :            : 
     502                 :          0 :         r = prompt_hostname();
     503         [ #  # ]:          0 :         if (r < 0)
     504                 :          0 :                 return r;
     505                 :            : 
     506         [ #  # ]:          0 :         if (isempty(arg_hostname))
     507                 :          0 :                 return 0;
     508                 :            : 
     509                 :          0 :         r = write_string_file(etc_hostname, arg_hostname,
     510                 :            :                               WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_SYNC | WRITE_STRING_FILE_MKDIR_0755);
     511         [ #  # ]:          0 :         if (r < 0)
     512         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write %s: %m", etc_hostname);
     513                 :            : 
     514         [ #  # ]:          0 :         log_info("%s written.", etc_hostname);
     515                 :          0 :         return 0;
     516                 :            : }
     517                 :            : 
     518                 :          0 : static int process_machine_id(void) {
     519                 :            :         const char *etc_machine_id;
     520                 :            :         char id[SD_ID128_STRING_MAX];
     521                 :            :         int r;
     522                 :            : 
     523   [ #  #  #  #  :          0 :         etc_machine_id = prefix_roota(arg_root, "/etc/machine-id");
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     524         [ #  # ]:          0 :         if (laccess(etc_machine_id, F_OK) >= 0)
     525                 :          0 :                 return 0;
     526                 :            : 
     527         [ #  # ]:          0 :         if (sd_id128_is_null(arg_machine_id))
     528                 :          0 :                 return 0;
     529                 :            : 
     530                 :          0 :         r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id),
     531                 :            :                               WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_SYNC | WRITE_STRING_FILE_MKDIR_0755);
     532         [ #  # ]:          0 :         if (r < 0)
     533         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write machine id: %m");
     534                 :            : 
     535         [ #  # ]:          0 :         log_info("%s written.", etc_machine_id);
     536                 :          0 :         return 0;
     537                 :            : }
     538                 :            : 
     539                 :          0 : static int prompt_root_password(void) {
     540                 :            :         const char *msg1, *msg2, *etc_shadow;
     541                 :            :         int r;
     542                 :            : 
     543         [ #  # ]:          0 :         if (arg_root_password)
     544                 :          0 :                 return 0;
     545                 :            : 
     546         [ #  # ]:          0 :         if (!arg_prompt_root_password)
     547                 :          0 :                 return 0;
     548                 :            : 
     549   [ #  #  #  #  :          0 :         etc_shadow = prefix_roota(arg_root, "/etc/shadow");
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     550         [ #  # ]:          0 :         if (laccess(etc_shadow, F_OK) >= 0)
     551                 :          0 :                 return 0;
     552                 :            : 
     553                 :          0 :         print_welcome();
     554                 :          0 :         putchar('\n');
     555                 :            : 
     556   [ #  #  #  #  :          0 :         msg1 = strjoina(special_glyph(SPECIAL_GLYPH_TRIANGULAR_BULLET), " Please enter a new root password (empty to skip):");
          #  #  #  #  #  
                #  #  # ]
     557   [ #  #  #  #  :          0 :         msg2 = strjoina(special_glyph(SPECIAL_GLYPH_TRIANGULAR_BULLET), " Please enter new root password again:");
          #  #  #  #  #  
                #  #  # ]
     558                 :            : 
     559                 :          0 :         for (;;) {
     560   [ #  #  #  #  :          0 :                 _cleanup_strv_free_erase_ char **a = NULL, **b = NULL;
                   #  # ]
     561                 :            : 
     562                 :          0 :                 r = ask_password_tty(-1, msg1, NULL, 0, 0, NULL, &a);
     563         [ #  # ]:          0 :                 if (r < 0)
     564         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to query root password: %m");
     565         [ #  # ]:          0 :                 if (strv_length(a) != 1) {
     566         [ #  # ]:          0 :                         log_warning("Received multiple passwords, where we expected one.");
     567                 :          0 :                         return -EINVAL;
     568                 :            :                 }
     569                 :            : 
     570         [ #  # ]:          0 :                 if (isempty(*a)) {
     571         [ #  # ]:          0 :                         log_warning("No password entered, skipping.");
     572                 :          0 :                         break;
     573                 :            :                 }
     574                 :            : 
     575                 :          0 :                 r = ask_password_tty(-1, msg2, NULL, 0, 0, NULL, &b);
     576         [ #  # ]:          0 :                 if (r < 0)
     577         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to query root password: %m");
     578                 :            : 
     579         [ #  # ]:          0 :                 if (!streq(*a, *b)) {
     580         [ #  # ]:          0 :                         log_error("Entered passwords did not match, please try again.");
     581                 :          0 :                         continue;
     582                 :            :                 }
     583                 :            : 
     584                 :          0 :                 arg_root_password = TAKE_PTR(*a);
     585                 :          0 :                 break;
     586                 :            :         }
     587                 :            : 
     588                 :          0 :         return 0;
     589                 :            : }
     590                 :            : 
     591                 :          0 : static int write_root_shadow(const char *path, const struct spwd *p) {
     592                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
     593                 :            :         int r;
     594                 :            : 
     595         [ #  # ]:          0 :         assert(path);
     596         [ #  # ]:          0 :         assert(p);
     597                 :            : 
     598         [ #  # ]:          0 :         RUN_WITH_UMASK(0777)
     599                 :          0 :                 f = fopen(path, "wex");
     600         [ #  # ]:          0 :         if (!f)
     601                 :          0 :                 return -errno;
     602                 :            : 
     603                 :          0 :         r = putspent_sane(p, f);
     604         [ #  # ]:          0 :         if (r < 0)
     605                 :          0 :                 return r;
     606                 :            : 
     607                 :          0 :         return fflush_sync_and_check(f);
     608                 :            : }
     609                 :            : 
     610                 :          0 : static int process_root_password(void) {
     611                 :            : 
     612                 :          0 :         struct spwd item = {
     613                 :            :                 .sp_namp = (char*) "root",
     614                 :            :                 .sp_min = -1,
     615                 :            :                 .sp_max = -1,
     616                 :            :                 .sp_warn = -1,
     617                 :            :                 .sp_inact = -1,
     618                 :            :                 .sp_expire = -1,
     619                 :            :                 .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
     620                 :            :         };
     621                 :          0 :         _cleanup_free_ char *salt = NULL;
     622                 :          0 :         _cleanup_close_ int lock = -1;
     623                 :          0 :         struct crypt_data cd = {};
     624                 :            : 
     625                 :            :         const char *etc_shadow;
     626                 :            :         int r;
     627                 :            : 
     628   [ #  #  #  #  :          0 :         etc_shadow = prefix_roota(arg_root, "/etc/shadow");
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     629         [ #  # ]:          0 :         if (laccess(etc_shadow, F_OK) >= 0)
     630                 :          0 :                 return 0;
     631                 :            : 
     632                 :          0 :         (void) mkdir_parents(etc_shadow, 0755);
     633                 :            : 
     634                 :          0 :         lock = take_etc_passwd_lock(arg_root);
     635         [ #  # ]:          0 :         if (lock < 0)
     636         [ #  # ]:          0 :                 return log_error_errno(lock, "Failed to take a lock: %m");
     637                 :            : 
     638   [ #  #  #  # ]:          0 :         if (arg_copy_root_password && arg_root) {
     639                 :            :                 struct spwd *p;
     640                 :            : 
     641                 :          0 :                 errno = 0;
     642                 :          0 :                 p = getspnam("root");
     643   [ #  #  #  # ]:          0 :                 if (p || errno != ENOENT) {
     644         [ #  # ]:          0 :                         if (!p) {
     645         [ #  # ]:          0 :                                 if (!errno)
     646                 :          0 :                                         errno = EIO;
     647                 :            : 
     648         [ #  # ]:          0 :                                 return log_error_errno(errno, "Failed to find shadow entry for root: %m");
     649                 :            :                         }
     650                 :            : 
     651                 :          0 :                         r = write_root_shadow(etc_shadow, p);
     652         [ #  # ]:          0 :                         if (r < 0)
     653         [ #  # ]:          0 :                                 return log_error_errno(r, "Failed to write %s: %m", etc_shadow);
     654                 :            : 
     655         [ #  # ]:          0 :                         log_info("%s copied.", etc_shadow);
     656                 :          0 :                         return 0;
     657                 :            :                 }
     658                 :            :         }
     659                 :            : 
     660                 :          0 :         r = prompt_root_password();
     661         [ #  # ]:          0 :         if (r < 0)
     662                 :          0 :                 return r;
     663                 :            : 
     664         [ #  # ]:          0 :         if (!arg_root_password)
     665                 :          0 :                 return 0;
     666                 :            : 
     667                 :          0 :         r = make_salt(&salt);
     668         [ #  # ]:          0 :         if (r < 0)
     669         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to get salt: %m");
     670                 :            : 
     671                 :          0 :         errno = 0;
     672                 :          0 :         item.sp_pwdp = crypt_r(arg_root_password, salt, &cd);
     673         [ #  # ]:          0 :         if (!item.sp_pwdp)
     674   [ #  #  #  # ]:          0 :                 return log_error_errno(errno == 0 ? SYNTHETIC_ERRNO(EINVAL) : errno,
     675                 :            :                                        "Failed to encrypt password: %m");
     676                 :            : 
     677                 :          0 :         item.sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
     678                 :            : 
     679                 :          0 :         r = write_root_shadow(etc_shadow, &item);
     680         [ #  # ]:          0 :         if (r < 0)
     681         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write %s: %m", etc_shadow);
     682                 :            : 
     683         [ #  # ]:          0 :         log_info("%s written.", etc_shadow);
     684                 :          0 :         return 0;
     685                 :            : }
     686                 :            : 
     687                 :          0 : static int help(void) {
     688                 :          0 :         _cleanup_free_ char *link = NULL;
     689                 :            :         int r;
     690                 :            : 
     691                 :          0 :         r = terminal_urlify_man("systemd-firstboot", "1", &link);
     692         [ #  # ]:          0 :         if (r < 0)
     693                 :          0 :                 return log_oom();
     694                 :            : 
     695                 :          0 :         printf("%s [OPTIONS...]\n\n"
     696                 :            :                "Configures basic settings of the system.\n\n"
     697                 :            :                "  -h --help                    Show this help\n"
     698                 :            :                "     --version                 Show package version\n"
     699                 :            :                "     --root=PATH               Operate on an alternate filesystem root\n"
     700                 :            :                "     --locale=LOCALE           Set primary locale (LANG=)\n"
     701                 :            :                "     --locale-messages=LOCALE  Set message locale (LC_MESSAGES=)\n"
     702                 :            :                "     --keymap=KEYMAP           Set keymap\n"
     703                 :            :                "     --timezone=TIMEZONE       Set timezone\n"
     704                 :            :                "     --hostname=NAME           Set host name\n"
     705                 :            :                "     --machine-ID=ID           Set machine ID\n"
     706                 :            :                "     --root-password=PASSWORD  Set root password\n"
     707                 :            :                "     --root-password-file=FILE Set root password from file\n"
     708                 :            :                "     --prompt-locale           Prompt the user for locale settings\n"
     709                 :            :                "     --prompt-keymap           Prompt the user for keymap settings\n"
     710                 :            :                "     --prompt-timezone         Prompt the user for timezone\n"
     711                 :            :                "     --prompt-hostname         Prompt the user for hostname\n"
     712                 :            :                "     --prompt-root-password    Prompt the user for root password\n"
     713                 :            :                "     --prompt                  Prompt for all of the above\n"
     714                 :            :                "     --copy-locale             Copy locale from host\n"
     715                 :            :                "     --copy-keymap             Copy keymap from host\n"
     716                 :            :                "     --copy-timezone           Copy timezone from host\n"
     717                 :            :                "     --copy-root-password      Copy root password from host\n"
     718                 :            :                "     --copy                    Copy locale, keymap, timezone, root password\n"
     719                 :            :                "     --setup-machine-id        Generate a new random machine ID\n"
     720                 :            :                "\nSee the %s for details.\n"
     721                 :            :                , program_invocation_short_name
     722                 :            :                , link
     723                 :            :         );
     724                 :            : 
     725                 :          0 :         return 0;
     726                 :            : }
     727                 :            : 
     728                 :          0 : static int parse_argv(int argc, char *argv[]) {
     729                 :            : 
     730                 :            :         enum {
     731                 :            :                 ARG_VERSION = 0x100,
     732                 :            :                 ARG_ROOT,
     733                 :            :                 ARG_LOCALE,
     734                 :            :                 ARG_LOCALE_MESSAGES,
     735                 :            :                 ARG_KEYMAP,
     736                 :            :                 ARG_TIMEZONE,
     737                 :            :                 ARG_HOSTNAME,
     738                 :            :                 ARG_MACHINE_ID,
     739                 :            :                 ARG_ROOT_PASSWORD,
     740                 :            :                 ARG_ROOT_PASSWORD_FILE,
     741                 :            :                 ARG_PROMPT,
     742                 :            :                 ARG_PROMPT_LOCALE,
     743                 :            :                 ARG_PROMPT_KEYMAP,
     744                 :            :                 ARG_PROMPT_TIMEZONE,
     745                 :            :                 ARG_PROMPT_HOSTNAME,
     746                 :            :                 ARG_PROMPT_ROOT_PASSWORD,
     747                 :            :                 ARG_COPY,
     748                 :            :                 ARG_COPY_LOCALE,
     749                 :            :                 ARG_COPY_KEYMAP,
     750                 :            :                 ARG_COPY_TIMEZONE,
     751                 :            :                 ARG_COPY_ROOT_PASSWORD,
     752                 :            :                 ARG_SETUP_MACHINE_ID,
     753                 :            :         };
     754                 :            : 
     755                 :            :         static const struct option options[] = {
     756                 :            :                 { "help",                 no_argument,       NULL, 'h'                      },
     757                 :            :                 { "version",              no_argument,       NULL, ARG_VERSION              },
     758                 :            :                 { "root",                 required_argument, NULL, ARG_ROOT                 },
     759                 :            :                 { "locale",               required_argument, NULL, ARG_LOCALE               },
     760                 :            :                 { "locale-messages",      required_argument, NULL, ARG_LOCALE_MESSAGES      },
     761                 :            :                 { "keymap",               required_argument, NULL, ARG_KEYMAP               },
     762                 :            :                 { "timezone",             required_argument, NULL, ARG_TIMEZONE             },
     763                 :            :                 { "hostname",             required_argument, NULL, ARG_HOSTNAME             },
     764                 :            :                 { "machine-id",           required_argument, NULL, ARG_MACHINE_ID           },
     765                 :            :                 { "root-password",        required_argument, NULL, ARG_ROOT_PASSWORD        },
     766                 :            :                 { "root-password-file",   required_argument, NULL, ARG_ROOT_PASSWORD_FILE   },
     767                 :            :                 { "prompt",               no_argument,       NULL, ARG_PROMPT               },
     768                 :            :                 { "prompt-locale",        no_argument,       NULL, ARG_PROMPT_LOCALE        },
     769                 :            :                 { "prompt-keymap",        no_argument,       NULL, ARG_PROMPT_KEYMAP        },
     770                 :            :                 { "prompt-timezone",      no_argument,       NULL, ARG_PROMPT_TIMEZONE      },
     771                 :            :                 { "prompt-hostname",      no_argument,       NULL, ARG_PROMPT_HOSTNAME      },
     772                 :            :                 { "prompt-root-password", no_argument,       NULL, ARG_PROMPT_ROOT_PASSWORD },
     773                 :            :                 { "copy",                 no_argument,       NULL, ARG_COPY                 },
     774                 :            :                 { "copy-locale",          no_argument,       NULL, ARG_COPY_LOCALE          },
     775                 :            :                 { "copy-keymap",          no_argument,       NULL, ARG_COPY_KEYMAP          },
     776                 :            :                 { "copy-timezone",        no_argument,       NULL, ARG_COPY_TIMEZONE        },
     777                 :            :                 { "copy-root-password",   no_argument,       NULL, ARG_COPY_ROOT_PASSWORD   },
     778                 :            :                 { "setup-machine-id",     no_argument,       NULL, ARG_SETUP_MACHINE_ID     },
     779                 :            :                 {}
     780                 :            :         };
     781                 :            : 
     782                 :            :         int r, c;
     783                 :            : 
     784         [ #  # ]:          0 :         assert(argc >= 0);
     785         [ #  # ]:          0 :         assert(argv);
     786                 :            : 
     787         [ #  # ]:          0 :         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
     788                 :            : 
     789   [ #  #  #  #  :          0 :                 switch (c) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     790                 :            : 
     791                 :          0 :                 case 'h':
     792                 :          0 :                         return help();
     793                 :            : 
     794                 :          0 :                 case ARG_VERSION:
     795                 :          0 :                         return version();
     796                 :            : 
     797                 :          0 :                 case ARG_ROOT:
     798                 :          0 :                         r = parse_path_argument_and_warn(optarg, true, &arg_root);
     799         [ #  # ]:          0 :                         if (r < 0)
     800                 :          0 :                                 return r;
     801                 :          0 :                         break;
     802                 :            : 
     803                 :          0 :                 case ARG_LOCALE:
     804         [ #  # ]:          0 :                         if (!locale_is_valid(optarg))
     805         [ #  # ]:          0 :                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     806                 :            :                                                        "Locale %s is not valid.", optarg);
     807                 :            : 
     808                 :          0 :                         r = free_and_strdup(&arg_locale, optarg);
     809         [ #  # ]:          0 :                         if (r < 0)
     810                 :          0 :                                 return log_oom();
     811                 :            : 
     812                 :          0 :                         break;
     813                 :            : 
     814                 :          0 :                 case ARG_LOCALE_MESSAGES:
     815         [ #  # ]:          0 :                         if (!locale_is_valid(optarg))
     816         [ #  # ]:          0 :                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     817                 :            :                                                        "Locale %s is not valid.", optarg);
     818                 :            : 
     819                 :          0 :                         r = free_and_strdup(&arg_locale_messages, optarg);
     820         [ #  # ]:          0 :                         if (r < 0)
     821                 :          0 :                                 return log_oom();
     822                 :            : 
     823                 :          0 :                         break;
     824                 :            : 
     825                 :          0 :                 case ARG_KEYMAP:
     826         [ #  # ]:          0 :                         if (!keymap_is_valid(optarg))
     827         [ #  # ]:          0 :                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     828                 :            :                                                        "Keymap %s is not valid.", optarg);
     829                 :            : 
     830                 :          0 :                         r = free_and_strdup(&arg_keymap, optarg);
     831         [ #  # ]:          0 :                         if (r < 0)
     832                 :          0 :                                 return log_oom();
     833                 :            : 
     834                 :          0 :                         break;
     835                 :            : 
     836                 :          0 :                 case ARG_TIMEZONE:
     837         [ #  # ]:          0 :                         if (!timezone_is_valid(optarg, LOG_ERR))
     838         [ #  # ]:          0 :                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     839                 :            :                                                        "Timezone %s is not valid.", optarg);
     840                 :            : 
     841                 :          0 :                         r = free_and_strdup(&arg_timezone, optarg);
     842         [ #  # ]:          0 :                         if (r < 0)
     843                 :          0 :                                 return log_oom();
     844                 :            : 
     845                 :          0 :                         break;
     846                 :            : 
     847                 :          0 :                 case ARG_ROOT_PASSWORD:
     848                 :          0 :                         r = free_and_strdup(&arg_root_password, optarg);
     849         [ #  # ]:          0 :                         if (r < 0)
     850                 :          0 :                                 return log_oom();
     851                 :          0 :                         break;
     852                 :            : 
     853                 :          0 :                 case ARG_ROOT_PASSWORD_FILE:
     854                 :          0 :                         arg_root_password = mfree(arg_root_password);
     855                 :            : 
     856                 :          0 :                         r = read_one_line_file(optarg, &arg_root_password);
     857         [ #  # ]:          0 :                         if (r < 0)
     858         [ #  # ]:          0 :                                 return log_error_errno(r, "Failed to read %s: %m", optarg);
     859                 :            : 
     860                 :          0 :                         break;
     861                 :            : 
     862                 :          0 :                 case ARG_HOSTNAME:
     863         [ #  # ]:          0 :                         if (!hostname_is_valid(optarg, true))
     864         [ #  # ]:          0 :                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     865                 :            :                                                        "Host name %s is not valid.", optarg);
     866                 :            : 
     867                 :          0 :                         hostname_cleanup(optarg);
     868                 :          0 :                         r = free_and_strdup(&arg_hostname, optarg);
     869         [ #  # ]:          0 :                         if (r < 0)
     870                 :          0 :                                 return log_oom();
     871                 :            : 
     872                 :          0 :                         break;
     873                 :            : 
     874                 :          0 :                 case ARG_MACHINE_ID:
     875         [ #  # ]:          0 :                         if (sd_id128_from_string(optarg, &arg_machine_id) < 0)
     876         [ #  # ]:          0 :                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     877                 :            :                                                        "Failed to parse machine id %s.", optarg);
     878                 :            : 
     879                 :          0 :                         break;
     880                 :            : 
     881                 :          0 :                 case ARG_PROMPT:
     882                 :          0 :                         arg_prompt_locale = arg_prompt_keymap = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true;
     883                 :          0 :                         break;
     884                 :            : 
     885                 :          0 :                 case ARG_PROMPT_LOCALE:
     886                 :          0 :                         arg_prompt_locale = true;
     887                 :          0 :                         break;
     888                 :            : 
     889                 :          0 :                 case ARG_PROMPT_KEYMAP:
     890                 :          0 :                         arg_prompt_keymap = true;
     891                 :          0 :                         break;
     892                 :            : 
     893                 :          0 :                 case ARG_PROMPT_TIMEZONE:
     894                 :          0 :                         arg_prompt_timezone = true;
     895                 :          0 :                         break;
     896                 :            : 
     897                 :          0 :                 case ARG_PROMPT_HOSTNAME:
     898                 :          0 :                         arg_prompt_hostname = true;
     899                 :          0 :                         break;
     900                 :            : 
     901                 :          0 :                 case ARG_PROMPT_ROOT_PASSWORD:
     902                 :          0 :                         arg_prompt_root_password = true;
     903                 :          0 :                         break;
     904                 :            : 
     905                 :          0 :                 case ARG_COPY:
     906                 :          0 :                         arg_copy_locale = arg_copy_keymap = arg_copy_timezone = arg_copy_root_password = true;
     907                 :          0 :                         break;
     908                 :            : 
     909                 :          0 :                 case ARG_COPY_LOCALE:
     910                 :          0 :                         arg_copy_locale = true;
     911                 :          0 :                         break;
     912                 :            : 
     913                 :          0 :                 case ARG_COPY_KEYMAP:
     914                 :          0 :                         arg_copy_keymap = true;
     915                 :          0 :                         break;
     916                 :            : 
     917                 :          0 :                 case ARG_COPY_TIMEZONE:
     918                 :          0 :                         arg_copy_timezone = true;
     919                 :          0 :                         break;
     920                 :            : 
     921                 :          0 :                 case ARG_COPY_ROOT_PASSWORD:
     922                 :          0 :                         arg_copy_root_password = true;
     923                 :          0 :                         break;
     924                 :            : 
     925                 :          0 :                 case ARG_SETUP_MACHINE_ID:
     926                 :            : 
     927                 :          0 :                         r = sd_id128_randomize(&arg_machine_id);
     928         [ #  # ]:          0 :                         if (r < 0)
     929         [ #  # ]:          0 :                                 return log_error_errno(r, "Failed to generate randomized machine ID: %m");
     930                 :            : 
     931                 :          0 :                         break;
     932                 :            : 
     933                 :          0 :                 case '?':
     934                 :          0 :                         return -EINVAL;
     935                 :            : 
     936                 :          0 :                 default:
     937                 :          0 :                         assert_not_reached("Unhandled option");
     938                 :            :                 }
     939                 :            : 
     940                 :          0 :         return 1;
     941                 :            : }
     942                 :            : 
     943                 :          0 : static int run(int argc, char *argv[]) {
     944                 :            :         bool enabled;
     945                 :            :         int r;
     946                 :            : 
     947                 :          0 :         r = parse_argv(argc, argv);
     948         [ #  # ]:          0 :         if (r <= 0)
     949                 :          0 :                 return r;
     950                 :            : 
     951                 :          0 :         log_setup_service();
     952                 :            : 
     953                 :          0 :         umask(0022);
     954                 :            : 
     955                 :          0 :         r = proc_cmdline_get_bool("systemd.firstboot", &enabled);
     956         [ #  # ]:          0 :         if (r < 0)
     957         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to parse systemd.firstboot= kernel command line argument, ignoring: %m");
     958   [ #  #  #  # ]:          0 :         if (r > 0 && !enabled)
     959                 :          0 :                 return 0; /* disabled */
     960                 :            : 
     961                 :          0 :         r = process_locale();
     962         [ #  # ]:          0 :         if (r < 0)
     963                 :          0 :                 return r;
     964                 :            : 
     965                 :          0 :         r = process_keymap();
     966         [ #  # ]:          0 :         if (r < 0)
     967                 :          0 :                 return r;
     968                 :            : 
     969                 :          0 :         r = process_timezone();
     970         [ #  # ]:          0 :         if (r < 0)
     971                 :          0 :                 return r;
     972                 :            : 
     973                 :          0 :         r = process_hostname();
     974         [ #  # ]:          0 :         if (r < 0)
     975                 :          0 :                 return r;
     976                 :            : 
     977                 :          0 :         r = process_machine_id();
     978         [ #  # ]:          0 :         if (r < 0)
     979                 :          0 :                 return r;
     980                 :            : 
     981                 :          0 :         r = process_root_password();
     982         [ #  # ]:          0 :         if (r < 0)
     983                 :          0 :                 return r;
     984                 :            : 
     985                 :          0 :         return 0;
     986                 :            : }
     987                 :            : 
     988                 :          0 : DEFINE_MAIN_FUNCTION(run);

Generated by: LCOV version 1.14