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.
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_
}
}
- // 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;
}
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;
#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
#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,
};
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;
{ \
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_
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;
}
#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_
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
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
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