]> Kevux Git Server - fll/commitdiff
Progress: init.
authorKevin Day <thekevinday@gmail.com>
Tue, 10 Nov 2020 02:21:04 +0000 (20:21 -0600)
committerKevin Day <thekevinday@gmail.com>
Tue, 10 Nov 2020 02:21:04 +0000 (20:21 -0600)
Begin preparations for implementing this.
After review, I suspect this will be more complex than the control and controller programs.
To that end, I am switching focus to those two programs.

level_3/init/c/init.c
level_3/init/c/init.h
level_3/init/c/main.c
level_3/init/c/private-init.c
level_3/init/c/private-init.h
level_3/init/data/build/dependencies
level_3/init/data/build/settings

index ded62b4fc4ebb93d9f1d253d96a7985c156c4efa..9d148013eb36f0bc1932524b728fb8de443a13f5 100644 (file)
@@ -14,14 +14,18 @@ extern "C" {
     fll_program_print_help_option(output, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, "    Output using colors that show up better on dark backgrounds.");
     fll_program_print_help_option(output, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, "   Output using colors that show up better on light backgrounds.");
     fll_program_print_help_option(output, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color.");
-    fll_program_print_help_option(output, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, "   Decrease verbosity beyond normal output.");
-    fll_program_print_help_option(output, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, "  Set verbosity to normal output.");
-    fll_program_print_help_option(output, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output.");
-    fll_program_print_help_option(output, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, "   Enable debugging, inceasing verbosity beyond normal output.");
     fll_program_print_help_option(output, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number.");
 
     fll_program_print_help_usage(output, context, init_name, "");
 
+    fl_color_print(output.stream, context.set.important, " Notes:");
+    fprintf(output.stream, "%c", f_string_eol[0]);
+
+    fprintf(output.stream, "  This program is intended to be directly called by the kernel during boot.%c", f_string_eol[0]);
+    fprintf(output.stream, "%c", f_string_eol[0]);
+
+    // @todo: this should still print the kernel command options.
+
     return F_none;
   }
 #endif // _di_init_print_help_
@@ -53,33 +57,6 @@ extern "C" {
         }
       }
 
-      // Identify priority of verbosity related parameters.
-      {
-        f_console_parameter_id_t ids[4] = { init_parameter_verbosity_quiet, init_parameter_verbosity_normal, init_parameter_verbosity_verbose, init_parameter_verbosity_debug };
-        f_console_parameter_id_t choice = 0;
-        const f_console_parameter_ids_t choices = f_macro_console_parameter_ids_t_initialize(ids, 4);
-
-        status = f_console_parameter_prioritize_right(parameters, choices, &choice);
-
-        if (F_status_is_error(status)) {
-          init_delete_data(data);
-          return status;
-        }
-
-        if (choice == init_parameter_verbosity_quiet) {
-          data->error.verbosity = f_console_verbosity_quiet;
-        }
-        else if (choice == init_parameter_verbosity_normal) {
-          data->error.verbosity = f_console_verbosity_normal;
-        }
-        else if (choice == init_parameter_verbosity_verbose) {
-          data->error.verbosity = f_console_verbosity_verbose;
-        }
-        else if (choice == init_parameter_verbosity_debug) {
-          data->error.verbosity = f_console_verbosity_debug;
-        }
-      }
-
       status = F_none;
     }
 
@@ -122,6 +99,13 @@ extern "C" {
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
 
+    f_macro_string_dynamic_t_delete_simple(data->setting_kernel.root);
+    f_macro_string_dynamic_t_delete_simple(data->setting_kernel.root_group);
+    f_macro_string_dynamic_t_delete_simple(data->setting_kernel.root_sub);
+    f_macro_string_dynamic_t_delete_simple(data->setting_kernel.run);
+    f_macro_string_dynamic_t_delete_simple(data->setting_kernel.settings);
+    f_macro_string_dynamic_t_delete_simple(data->setting_kernel.settings_name);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index 2742d4d85dfb74a478d12a73ea56de57c8cc3a36..f28bf2dbe51f17c8e74fb06b594769d8dc93d9d4 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef _init_h
 
 // libc includes
+#include <sys/mount.h>
 
 // fll-0 includes
 #include <level_0/type.h>
 #include <level_0/console.h>
 #include <level_0/directory.h>
 #include <level_0/file.h>
-#include <level_0/pipe.h>
+#include <level_0/iki.h>
 #include <level_0/print.h>
+#include <level_0/signal.h>
 
 // fll-1 includes
 #include <level_1/color.h>
-#include <level_1/console.h>
+#include <level_1/iki.h>
 #include <level_1/string.h>
 
 // fll-2 includes
@@ -58,16 +60,106 @@ extern "C" {
 #endif // _di_init_name_
 
 #ifndef _di_init_defines_
+  #define init_string_classic       "classic"
+  #define init_string_color         "color" // for specifying color mode.
+  #define init_string_custom        "custom"
+  #define init_string_dark          "dark"
+  #define init_string_debug         "debug"
+  #define init_string_failsafe      "failsafe" // default to /bin/bash if provided failsafe is invalid, or prompt for valid??.
+  #define init_string_light         "light"
+  #define init_string_maintenance   "maintenance"
+  #define init_string_mode          "mode"
+  #define init_string_no            "no"
+  #define init_string_normal        "normal"
+  #define init_string_quiet         "quiet"
+  #define init_string_root          "root"
+  #define init_string_root_group    "root_group" // floating root group id (such as d_root).
+  #define init_string_root_mode     "root_mode"  // floating root mode (such as 2751).
+  #define init_string_root_size     "root_size"
+  #define init_string_root_sub      "root_sub" // was "subroot".
+  #define init_string_run           "run"
+  #define init_string_settings      "settings"
+  #define init_string_settings_name "settings_name"
+  #define init_string_squash        "squash"
+  #define init_string_squish        "squish"
+  #define init_string_verbose       "verbose"
+  #define init_string_verbosity     "verbosity" // quite, normal, verbose, debug
+  #define init_string_yes           "yes"
+
+  #define init_string_classic_length       7
+  #define init_string_color_length         5
+  #define init_string_custom_length        6
+  #define init_string_dark_length          4
+  #define init_string_debug_length         5
+  #define init_string_failsafe_length      8
+  #define init_string_light_length         5
+  #define init_string_maintenance_length   11
+  #define init_string_mode_length          4
+  #define init_string_no_length            2
+  #define init_string_normal_length        6
+  #define init_string_quiet_length         5
+  #define init_string_root_length          4
+  #define init_string_root_group_length    10
+  #define init_string_root_mode_length     9
+  #define init_string_root_size_length     9
+  #define init_string_root_sub_length      8
+  #define init_string_run_length           3
+  #define init_string_settings_length      8
+  #define init_string_settings_name_length 13
+  #define init_string_squash_length        6
+  #define init_string_squish_length        6
+  #define init_string_verbose_length       7
+  #define init_string_verbosity_length     9
+  #define init_string_yes_length           3
+
+  #define init_path_proc         "/proc"
+  #define init_path_proc_cmdline "/proc/cmdline"
+  #define init_path_settings_0   "settings"
+  #define init_path_settings_1   ".settings"
+
+  #define init_path_proc_lenght         5
+  #define init_path_proc_cmdline_length 13
+  #define init_path_settings_0_length   8
+  #define init_path_settings_1_length   9
+
+  #define init_path_extension_device ".device"
+  #define init_path_extension_lock   ".lock"
+  #define init_path_extension_squash ".sfs"
+
+  #define init_path_extension_device_length 7
+  #define init_path_extension_lock_length   5
+  #define init_path_extension_squash_length 3
+
+  #define init_device_by_device    "device"   // such as: "pci-0000:00:1.0-ata-1"
+  #define init_device_by_id        "id"       // such as: "ata-WIN_SSD_1234567890123"
+  #define init_device_by_label     "label"    // such as: "my_usb" from LABEL="my_usb"
+  #define init_device_by_path      "path"     // such as: "sda1"
+  #define init_device_by_type      "type"     // such as: "ext4"
+  #define init_device_by_uuid      "uuid"     // such as: "80a2a094-8536-46d9-aa54-cd34c142422b" from UUID="80a2a094-8536-46d9-aa54-cd34c142422b"
+  #define init_device_by_uuid_part "partuuid" // such as: "0abcdef1-23" from PARTUUID="0abcdef1-34"
+
+  #define init_device_by_device_length    6
+  #define init_device_by_id_length        2
+  #define init_device_by_label_length     5
+  #define init_device_by_path_length      4
+  #define init_device_by_type_length      4
+  #define init_device_by_uuid_length      4
+  #define init_device_by_uuid_part_length 8
+
+  enum {
+    init_mode_classic = 1,
+    init_mode_custom,
+    init_mode_maintenance,
+    init_mode_normal,
+    init_mode_squash,
+    init_mode_squish,
+  };
 
   enum {
     init_parameter_help,
     init_parameter_light,
     init_parameter_dark,
     init_parameter_no_color,
-    init_parameter_verbosity_quiet,
-    init_parameter_verbosity_normal,
-    init_parameter_verbosity_verbose,
-    init_parameter_verbosity_debug,
     init_parameter_version,
   };
 
@@ -77,26 +169,89 @@ extern "C" {
       f_console_parameter_t_initialize(f_console_standard_short_light, f_console_standard_long_light, 0, 0, f_console_type_inverse), \
       f_console_parameter_t_initialize(f_console_standard_short_dark, f_console_standard_long_dark, 0, 0, f_console_type_inverse), \
       f_console_parameter_t_initialize(f_console_standard_short_no_color, f_console_standard_long_no_color, 0, 0, f_console_type_inverse), \
-      f_console_parameter_t_initialize(f_console_standard_short_quiet, f_console_standard_long_quiet, 0, 0, f_console_type_inverse), \
-      f_console_parameter_t_initialize(f_console_standard_short_normal, f_console_standard_long_normal, 0, 0, f_console_type_inverse), \
-      f_console_parameter_t_initialize(f_console_standard_short_verbose, f_console_standard_long_verbose, 0, 0, f_console_type_inverse), \
-      f_console_parameter_t_initialize(f_console_standard_short_debug, f_console_standard_long_debug, 0, 0, f_console_type_inverse), \
       f_console_parameter_t_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, 0, f_console_type_inverse), \
     }
 
-  #define init_total_parameters 9
+  #define init_total_parameters 5
 #endif // _di_init_defines_
 
+#ifndef _di_init_setting_kernel_t_
+  typedef struct {
+    bool failsafe;
+
+    bool lock_color;
+    bool lock_devices;
+    bool lock_failsafe;
+    bool lock_mode;
+    bool lock_root;
+    bool lock_root_group;
+    bool lock_root_mode;
+    bool lock_root_size;
+    bool lock_root_sub;
+    bool lock_run;
+    bool lock_settings;
+    bool lock_settings_name;
+    bool lock_verbosity;
+
+    uint8_t color;
+    uint8_t mode;
+    uint8_t root_mode;
+    uint8_t verbosity;
+
+    f_number_unsigned_t root_size;
+
+    f_string_dynamic_t root;
+    f_string_dynamic_t root_group;
+    f_string_dynamic_t root_sub;
+    f_string_dynamic_t run;
+    f_string_dynamic_t settings;
+    f_string_dynamic_t settings_name;
+  } init_setting_kernel_t;
+
+  #define init_setting_kernel_t_initialize \
+    { \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      F_false, \
+      0, \
+      0, \
+      0, \
+      0, \
+      0, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+    }
+#endif // _di_init_setting_kernel_
+
 #ifndef _di_init_data_t_
   typedef struct {
     f_console_parameter_t parameters[init_total_parameters];
 
     f_string_lengths_t remaining;
-    bool process_pipe;
 
     f_file_t output;
     fll_error_print_t error;
 
+    mode_t umask;
+    f_signal_t signal;
+
+    init_setting_kernel_t setting_kernel;
+
     f_color_context_t context;
   } init_data_t;
 
@@ -104,9 +259,11 @@ extern "C" {
     { \
       init_console_parameter_t_initialize, \
       f_string_lengths_t_initialize, \
-      F_false, \
       f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \
       fll_error_print_t_initialize, \
+      0, \
+      f_signal_t_initialize, \
+      init_setting_kernel_t_initialize, \
       f_color_context_t_initialize, \
     }
 #endif // _di_init_data_t_
index a603896a55fbf3b54cd9a01128bd75251da72470..e6fe0306b228cf70d90a58b746db0fd0cfe93533 100644 (file)
@@ -3,12 +3,33 @@
 int main(const unsigned long argc, const f_string_t *argv) {
   const f_console_arguments_t arguments = { argc, argv };
   init_data_t data = init_data_initialize;
+  f_status_t status = F_none;
 
-  if (f_pipe_input_exists()) {
-    data.process_pipe = F_true;
+  f_signal_set_empty(&data.signal.set);
+  f_signal_set_add(F_signal_abort, &data.signal.set);
+  f_signal_set_add(F_signal_hangup, &data.signal.set);
+  f_signal_set_add(F_signal_interrupt, &data.signal.set);
+  f_signal_set_add(F_signal_quit, &data.signal.set);
+  f_signal_set_add(F_signal_termination, &data.signal.set);
+  f_signal_set_handle(SIG_BLOCK, &data.signal.set);
+
+  // if there is an error opening a signal descriptor, then do not handle signals.
+  if (F_status_is_error(f_signal_open(&data.signal))) {
+    f_signal_set_handle(SIG_UNBLOCK, &data.signal.set);
+    f_signal_close(&data.signal);
   }
 
-  if (F_status_is_error(init_main(arguments, &data))) {
+  // @fixme: bad design in POSIX where there is no get umask without setting it.
+  data.umask = umask(0);
+
+  // restore umask.
+  umask(data.umask);
+
+  status = init_main(arguments, &data);
+
+  f_signal_close(&data.signal);
+
+  if (F_status_is_error(status)) {
     return 1;
   }
 
index 9130e06237f732b502bd523c1102e54eef9145cd..c81074946f1dc75424246a12c858ff3fad2713bd 100644 (file)
@@ -1,2 +1,374 @@
 #include "init.h"
 #include "private-init.h"
+
+/*
+Use the initrd_init source to base this project off, but be a little more generic than Kevux specific.
+1: mount temporary proc
+2: read kernel command line, look for (use IKI syntax?):
+ - setting:""
+ - failsafe:"" (such as failsafe:"/bin/bash")
+ - root:"" (such as root:"" (for floating root), root:"/dev/abc", root:"UUID:0000")
+ - subroot:""
+ - mode:"" (such as mode:"squash", mode:"squish", mode:"maintenance", mode:"classic", mode:"install")
+ - run:"" (was "finalinit", such as run:"/sbin/init" or run:"/bin/bash")
+ - setting_name="" (such as a name fo the settings file).
+3: act based on those options.
+4: create and mount floating root.
+5: unmount temporary proc and anything else that is temporary.
+6: perform pivot root.
+7: perform chroot.
+8: perform any setup tasks.
+9: execute program from run:"".
+10: at any point on error, print error the execute failsafe:"".
+
+Settings should utilize/process:
+- blkid, find devices (is there a blkid library?).
+- mdadm, for mounting any raid devices.
+- cryptsetup, for decrypting a device.
+- squashfs, unsquashfs
+
+Support ".lock" files to lock out adding custom command line parameters (such as home.lock to prevent home_device:"" from being used).
+Support "settings/" or ".settings/".
+Support ".sfs" loopback mounting.
+
+process /proc/partitions, and support things like: LABEL=.
+consider matching partition types as well.
+Consider the "*.device" files such that they are also use IKI.
+*/
+
+#ifndef _di_init_load_failsafe_
+  f_return_status init_load_failsafe(const init_data_t data) {
+
+    return F_none;
+  }
+#endif // _di_init_load_failsafe_
+
+#ifndef _di_init_load_kernel_setting_
+  f_return_status init_load_kernel_setting(const init_data_t data, init_setting_kernel_t *setting_kernel) {
+    f_status_t status = F_none;
+
+    status = f_directory_exists(init_path_proc_cmdline);
+
+    if (F_status_is_error(status)) {
+      fll_error_file_print(data.error, F_status_set_fine(status), "f_directory_exists", F_true, init_path_proc_cmdline, "exists", fll_error_file_type_directory);
+      return status;
+    }
+
+    if (status == F_false) {
+      status = f_directory_create(init_path_proc_cmdline, f_file_mode_user_directory);
+
+      if (F_status_is_error(status)) {
+        fll_error_file_print(data.error, F_status_set_fine(status), "f_directory_create", F_true, init_path_proc_cmdline, "create", fll_error_file_type_directory);
+        return status;
+      }
+    }
+
+    f_file_t command_line = f_file_t_initialize;
+
+    // Note: this will specifically not be unmounted on error.
+    mount("proc", init_path_proc_cmdline, "proc", 0, "");
+
+    status = f_file_stream_open(init_path_proc_cmdline, 0, &command_line);
+
+    if (F_status_is_error(status)) {
+      fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_open", F_true, init_path_proc_cmdline, "open", fll_error_file_type_file);
+      return status;
+    }
+
+    if (init_signal_received(data)) {
+      f_file_stream_close(F_true, &command_line);
+      return F_signal;
+    }
+
+    f_string_dynamic_t buffer = f_string_dynamic_t_initialize;
+
+    status = f_file_stream_read(command_line, 1, &buffer);
+
+    if (F_status_is_error(status)) {
+      fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_read", F_true, init_path_proc_cmdline, "read", fll_error_file_type_file);
+    }
+
+    if (F_status_is_error_not(status)) {
+      f_string_dynamic_t cache = f_string_dynamic_t_initialize;
+
+      // set used to 1 with size of 0 to represent that the parameter was not specified via the kernel command line.
+      setting_kernel->root.used = 1;
+      setting_kernel->root_group.used = 1;
+      setting_kernel->root_sub.used = 1;
+      setting_kernel->run.used = 1;
+      setting_kernel->settings.used = 1;
+      setting_kernel->settings_name.used = 1;
+
+      const f_string_t parameter_name[] = {
+        init_string_color,
+        init_string_failsafe,
+        init_string_mode,
+        init_string_root,
+        init_string_root_group,
+        init_string_root_mode,
+        init_string_root_size,
+        init_string_root_sub,
+        init_string_run,
+        init_string_settings,
+        init_string_settings_name,
+        init_string_verbosity,
+      };
+
+      const f_string_length_t parameter_length[] = {
+        init_string_color_length,
+        init_string_failsafe_length,
+        init_string_mode_length,
+        init_string_root_length,
+        init_string_root_group_length,
+        init_string_root_mode_length,
+        init_string_root_size_length,
+        init_string_root_sub_length,
+        init_string_run_length,
+        init_string_settings_length,
+        init_string_settings_name_length,
+        init_string_verbosity_length,
+      };
+
+      f_string_dynamic_t *parameter_value[] = {
+        &cache,
+        &cache,
+        &cache,
+        &setting_kernel->root,
+        &setting_kernel->root_group,
+        &cache,
+        &cache,
+        &setting_kernel->root_sub,
+        &setting_kernel->run,
+        &setting_kernel->settings,
+        &setting_kernel->settings_name,
+        &cache,
+      };
+
+      bool *parameter_value_bool[] = {
+        0,
+        &setting_kernel->failsafe,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+      };
+
+      uint8_t *parameter_value_uint8[] = {
+        &setting_kernel->color,
+        0,
+        &setting_kernel->mode,
+        0,
+        0,
+        &setting_kernel->root_mode,
+        0,
+        0,
+        0,
+        0,
+        0,
+        &setting_kernel->verbosity,
+      };
+
+      // @todo: create f_metric_t, such that it is an f_number_unsigned_t with an exponent type, such as: Y (yotta), Z (zetta), E (exa), P (peta), T (Tera), G (giga), M (mega), k (kilo), h (hecto), da (deca), (none), d (deci), c (centi), m (milli), μ (micro), n (nano), p (pico), f (femto), a (atto), z (zepto), and y (yocto).
+      f_number_unsigned_t *parameter_value_number_unsigned[] = {
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        &setting_kernel->root_size,
+        0,
+        0,
+        0,
+        0,
+        0,
+      };
+
+      // 0 = string, 1 = yes/no, 2 = file mode, 3 = quiet, normal, verbose, or debug, 4 = light, dark, or no, 5 = init mode, 6 = size.
+      const uint8_t parameter_type[] = {
+        4,
+        1,
+        5,
+        0,
+        0,
+        2,
+        6,
+        0,
+        0,
+        0,
+        0,
+        3,
+      };
+
+      f_iki_variable_t variable = f_iki_variable_t_initialize;
+      f_iki_vocabulary_t vocabulary = f_iki_vocabulary_t_initialize;
+      f_iki_content_t content = f_iki_content_t_initialize;
+
+      {
+        f_string_range_t range = f_macro_string_range_t_initialize(buffer.used);
+
+        status = fl_iki_read(&buffer, &range, &variable, &vocabulary, &content);
+      }
+
+      {
+        f_string_length_t i = 0;
+        f_string_length_t j = 0;
+
+        for (; i < variable.used; ++i) {
+
+          for (j = 0; j < 12; ++j) {
+
+            if (fl_string_dynamic_partial_compare_string(parameter_name[i], buffer, parameter_length[i], vocabulary.array[j]) == F_equal_to) {
+              parameter_value[j]->used = 0;
+
+              if (content.array[j].start <= content.array[j].stop) {
+                status = fl_string_dynamic_partial_append(buffer, content.array[j], parameter_value[j]);
+
+                if (F_status_is_error(status)) {
+                  fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append", F_true);
+
+                  i = variable.used;
+                  break;
+                }
+              }
+
+              if (parameter_type[i] == 0) {
+                // nothing to do.
+              }
+              else if (parameter_type[i] == 1) {
+
+                if (fl_string_dynamic_compare_string(init_string_yes, *parameter_value[j], init_string_yes_length) == F_equal_to) {
+                  *parameter_value_bool[i] = F_true;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_yes, *parameter_value[j], init_string_no_length) == F_equal_to) {
+                  *parameter_value_bool[i] = F_false;
+                }
+                else {
+                  // @todo: warning about invalid value (save to an array and then print after settings are processed?)
+                }
+              }
+              else if (parameter_type[i] == 2) {
+                // @todo: use same kind of logic as used in fake.
+              }
+              else if (parameter_type[i] == 3) {
+                if (fl_string_dynamic_compare_string(init_string_quiet, *parameter_value[j], init_string_quiet_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = f_console_verbosity_quiet;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_normal, *parameter_value[j], init_string_normal_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = f_console_verbosity_normal;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_verbose, *parameter_value[j], init_string_verbose_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = f_console_verbosity_verbose;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_debug, *parameter_value[j], init_string_debug_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = f_console_verbosity_debug;
+                }
+                else {
+                  // @todo: warning about invalid value (save to an array and then print after settings are processed?)
+                }
+              }
+              else if (parameter_type[i] == 4) {
+                if (fl_string_dynamic_compare_string(init_string_dark, *parameter_value[j], init_string_dark_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = f_color_mode_dark;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_light, *parameter_value[j], init_string_light_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = f_color_mode_light;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_no, *parameter_value[j], init_string_no_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = f_color_mode_no_color;
+                }
+                else {
+                  // @todo: warning about invalid value (save to an array and then print after settings are processed?)
+                }
+              }
+              else if (parameter_type[i] == 5) {
+                if (fl_string_dynamic_compare_string(init_string_classic, *parameter_value[j], init_string_classic_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = init_mode_classic;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_custom, *parameter_value[j], init_string_custom_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = init_mode_custom;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_maintenance, *parameter_value[j], init_string_maintenance_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = init_mode_maintenance;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_normal, *parameter_value[j], init_string_normal_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = init_mode_normal;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_squash, *parameter_value[j], init_string_squash_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = init_mode_squash;
+                }
+                else if (fl_string_dynamic_compare_string(init_string_squish, *parameter_value[j], init_string_squish_length) == F_equal_to) {
+                  *parameter_value_uint8[i] = init_mode_squish;
+                }
+                else {
+                  // @todo: warning about invalid value (save to an array and then print after settings are processed?)
+                }
+              }
+              else if (parameter_type[i] == 6) {
+                // @todo
+                // fl_conversion_string_to_number_unsigned
+              }
+              else {
+                // @todo: warning about unknown IKI in verbose mode (save to an array and then print after settings are processed?)
+              }
+            }
+          } // for
+        } // for
+      }
+
+      f_macro_iki_variable_t_delete_simple(variable);
+      f_macro_iki_vocabulary_t_delete_simple(vocabulary);
+      f_macro_iki_content_t_delete_simple(content);
+      f_macro_string_dynamic_t_delete_simple(cache);
+    }
+
+    f_file_stream_close(F_true, &command_line);
+
+    f_macro_string_dynamic_t_delete_simple(buffer);
+
+    return status;
+  }
+#endif // _di_init_load_kernel_setting_
+
+#ifndef _di_init_signal_read_
+  f_return_status init_signal_received(const init_data_t data) {
+
+    if (!data.signal.id) {
+      return F_false;
+    }
+
+    f_status_t status = F_none;
+
+    struct signalfd_siginfo information;
+
+    memset(&information, 0, sizeof(struct signalfd_siginfo));
+
+    status = f_signal_read(data.signal, &information);
+
+    if (status == F_signal) {
+      switch (information.ssi_signo) {
+        case F_signal_abort:
+        case F_signal_hangup:
+        case F_signal_interrupt:
+        case F_signal_quit:
+        case F_signal_termination:
+
+          if (data.error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+            fl_color_print(data.error.to.stream, data.context.set.error, "ALERT: An appropriate exit signal has been received, now aborting.");
+            fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+          }
+
+          return F_true;
+      }
+    }
+
+    return F_false;
+  }
+#endif // _di_init_signal_read_
index b630b672e5c16da74eb996c8ea9a07c7b42a5ae8..4641a612bcd709414f2d63219c5698f9192c6015 100644 (file)
 extern "C" {
 #endif
 
+/**
+ * @todo
+ */
+#ifndef _di_init_load_failsafe_
+  extern f_return_status init_load_failsafe(const init_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_init_load_failsafe_
+
+/**
+ * @todo
+ */
+#ifndef _di_init_load_kernel_setting_
+  extern f_return_status init_load_kernel_setting(const init_data_t data, init_setting_kernel_t *setting_kernel) f_gcc_attribute_visibility_internal;
+#endif // _di_init_load_kernel_setting_
+
+/**
+ * Check to see if a termination signal has been received.
+ *
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_true if a termination signal is received.
+ *   F_false if no termination signal is received.
+ *
+ *   Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_init_signal_read_
+  extern f_return_status init_signal_received(const init_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_init_signal_read_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 3b53a6c7f25e2bde063c201eccd5127f9e8bbbf5..0de85e913d8ddfec7d49c450c19f9e0ca134b617 100644 (file)
@@ -7,11 +7,14 @@ f_string
 f_utf
 f_color
 f_console
+f_conversion
 f_file
-f_pipe
+f_iki
 f_print
+f_signal
 fl_color
-fl_console
+fl_conversion
+fl_iki
 fl_string
 fll_error
 fll_program
index ca7867da4c713e34b1e09fc1608a40a0bce95b72..699aa00fd7eefc74e6fc9a0625a08a5f7207ef7a 100644 (file)
@@ -19,7 +19,7 @@ build_compiler gcc
 build_indexer ar
 build_language c
 build_libraries -lc
-build_libraries-individual -lfll_error -lfll_program -lfll_status -lfl_color -lfl_console -lfl_status -lfl_string -lf_console -lf_conversion -lf_file -lf_memory -lf_pipe -lf_print -lf_utf
+build_libraries-individual -lfll_error -lfll_program -lfll_status -lfl_color -lfl_conversion -lfl_iki -lfl_status -lfl_string -lf_console -lf_conversion -lf_file -lf_iki -lf_memory -lf_print -lf_signal -lf_utf
 build_libraries-level -lfll_2 -lfll_1 -lfll_0
 build_libraries-monolithic -lfll
 build_sources_library init.c private-init.c