]> Kevux Git Server - fll/commitdiff
Progress: Refactoring firewall from 0.6.x to 0.7.x/0.8.x and other FLL project wide...
authorKevin Day <kevin@kevux.org>
Sun, 11 Feb 2024 04:14:23 +0000 (22:14 -0600)
committerKevin Day <kevin@kevux.org>
Sun, 11 Feb 2024 04:14:23 +0000 (22:14 -0600)
Add the f_console_parameter_state_type_total_d and update all programs.
Add (and use) additional f_string_format strings.
Add fll_program_print_help_operations().
Add fll_program_print_help_special_options().
Begin using more helper flags for common behavior, such as "main_flag_version_copyright_help" type of flags.
Add missing documentation comments for some functions.
Remove duplicate "#ifdef __cplusplus" blocks in several programs.

Begin to refactoring firewall to follow the 0.7.x and eventually 0.8.x project design.
The firewall program is far from ready and will not yet compile.

118 files changed:
build/disable/level_2/fll_program.h
build/stand_alone/fake.config.h
level_0/f_console/c/console/common.h
level_0/f_string/c/string/static.c
level_0/f_string/c/string/static.h
level_2/fll_program/c/program/print.c
level_2/fll_program/c/program/print.h
level_3/byte_dump/c/main/byte_dump.c
level_3/byte_dump/c/main/common/enumeration.h
level_3/byte_dump/c/main/print/error.c
level_3/byte_dump/c/main/print/error.h
level_3/byte_dump/c/main/print/message.c
level_3/byte_dump/c/main/thread.c
level_3/control/c/main/common/enumeration.h
level_3/control/c/main/control.c
level_3/control/c/main/print/error.c
level_3/control/c/main/print/error.h
level_3/control/c/main/print/warning.c
level_3/control/c/main/thread.c
level_3/controller/c/common.h
level_3/controller/c/controller/private-controller.c
level_3/controller/c/rule/private-rule.c
level_3/fake/c/main/common/enumeration.h
level_3/fake/c/main/fake.c
level_3/fake/c/main/print/error.c
level_3/fake/c/main/print/error.h
level_3/fake/c/main/print/message.c
level_3/fake/c/main/print/verbose.h
level_3/fake/c/main/print/warning.h
level_3/fake/c/main/thread.c
level_3/firewall/c/firewall.c [deleted file]
level_3/firewall/c/firewall.h [deleted file]
level_3/firewall/c/main/common.c [new file with mode: 0644]
level_3/firewall/c/main/common.h [new file with mode: 0644]
level_3/firewall/c/main/common/define.c [new file with mode: 0644]
level_3/firewall/c/main/common/define.h [new file with mode: 0644]
level_3/firewall/c/main/common/enumeration.c [new file with mode: 0644]
level_3/firewall/c/main/common/enumeration.h [new file with mode: 0644]
level_3/firewall/c/main/common/print.c [new file with mode: 0644]
level_3/firewall/c/main/common/print.h [new file with mode: 0644]
level_3/firewall/c/main/common/string.c [moved from level_3/firewall/c/common.c with 57% similarity]
level_3/firewall/c/main/common/string.h [moved from level_3/firewall/c/common.h with 50% similarity]
level_3/firewall/c/main/common/type.c [new file with mode: 0644]
level_3/firewall/c/main/common/type.h [new file with mode: 0644]
level_3/firewall/c/main/firewall.c [new file with mode: 0644]
level_3/firewall/c/main/firewall.h [new file with mode: 0644]
level_3/firewall/c/main/main.c [moved from level_3/firewall/c/main.c with 51% similarity]
level_3/firewall/c/main/main.h [moved from level_3/firewall/c/main.h with 97% similarity]
level_3/firewall/c/main/operate.c [new file with mode: 0644]
level_3/firewall/c/main/operate.h [new file with mode: 0644]
level_3/firewall/c/main/operate/buffer.c [new file with mode: 0644]
level_3/firewall/c/main/operate/buffer.h [new file with mode: 0644]
level_3/firewall/c/main/operate/create.c [new file with mode: 0644]
level_3/firewall/c/main/operate/create.h [new file with mode: 0644]
level_3/firewall/c/main/operate/default.c [new file with mode: 0644]
level_3/firewall/c/main/operate/default.h [new file with mode: 0644]
level_3/firewall/c/main/operate/delete.c [new file with mode: 0644]
level_3/firewall/c/main/operate/delete.h [new file with mode: 0644]
level_3/firewall/c/main/operate/load.c [new file with mode: 0644]
level_3/firewall/c/main/operate/load.h [new file with mode: 0644]
level_3/firewall/c/main/operate/process.c [new file with mode: 0644]
level_3/firewall/c/main/operate/process.h [new file with mode: 0644]
level_3/firewall/c/main/print/data.c [new file with mode: 0644]
level_3/firewall/c/main/print/data.h [new file with mode: 0644]
level_3/firewall/c/main/print/debug.c [new file with mode: 0644]
level_3/firewall/c/main/print/debug.h [new file with mode: 0644]
level_3/firewall/c/main/print/error.c [new file with mode: 0644]
level_3/firewall/c/main/print/error.h [new file with mode: 0644]
level_3/firewall/c/main/print/message.c [new file with mode: 0644]
level_3/firewall/c/main/print/message.h [new file with mode: 0644]
level_3/firewall/c/main/print/verbose.c [new file with mode: 0644]
level_3/firewall/c/main/print/verbose.h [new file with mode: 0644]
level_3/firewall/c/main/print/warning.c [new file with mode: 0644]
level_3/firewall/c/main/print/warning.h [new file with mode: 0644]
level_3/firewall/c/main/signal.c [new file with mode: 0644]
level_3/firewall/c/main/signal.h [new file with mode: 0644]
level_3/firewall/c/main/thread.c [new file with mode: 0644]
level_3/firewall/c/main/thread.h [new file with mode: 0644]
level_3/firewall/c/print.c [deleted file]
level_3/firewall/c/print.h [deleted file]
level_3/firewall/c/private-common.c [deleted file]
level_3/firewall/c/private-common.h [deleted file]
level_3/firewall/c/private-firewall.c [deleted file]
level_3/firewall/c/private-firewall.h [deleted file]
level_3/fss_identify/c/main/common/enumeration.h
level_3/fss_identify/c/main/fss_identify.c
level_3/fss_identify/c/main/load.c
level_3/fss_identify/c/main/print/data.h
level_3/fss_identify/c/main/print/error.c
level_3/fss_identify/c/main/print/error.h
level_3/fss_identify/c/main/print/message.h
level_3/fss_identify/c/main/process.c
level_3/fss_identify/c/main/thread.c
level_3/fss_read/c/main/common/enumeration.h
level_3/fss_read/c/main/fss_read.c
level_3/fss_read/c/main/print/error.c
level_3/fss_read/c/main/thread.c
level_3/fss_read/c/payload/print.c
level_3/fss_write/c/main/common/enumeration.h
level_3/fss_write/c/main/fss_write.c
level_3/fss_write/c/main/thread.c
level_3/iki_read/c/main/common/enumeration.h
level_3/iki_read/c/main/iki_read.c
level_3/iki_read/c/main/print/error.h
level_3/iki_read/c/main/thread.c
level_3/iki_write/c/main/common/enumeration.h
level_3/iki_write/c/main/iki_write.c
level_3/iki_write/c/main/print/error.h
level_3/iki_write/c/main/thread.c
level_3/status_code/c/main/common/enumeration.h
level_3/status_code/c/main/print/error.h
level_3/status_code/c/main/status_code.c
level_3/status_code/c/main/thread.c
level_3/utf8/c/main/common/enumeration.h
level_3/utf8/c/main/print/error.c
level_3/utf8/c/main/print/error.h
level_3/utf8/c/main/thread.c
level_3/utf8/c/main/utf8.c

index 68b0703..31e520e 100644 (file)
 #define _di_fll_program_print_error_pipe_missing_content_
 #define _di_fll_program_print_error_pipe_object_without_content_
 #define _di_fll_program_print_help_header_
+#define _di_fll_program_print_help_operations_
 #define _di_fll_program_print_help_option_
 #define _di_fll_program_print_help_option_long_
 #define _di_fll_program_print_help_option_other_
 #define _di_fll_program_print_help_option_standard_
+#define _di_fll_program_print_help_special_options_
 #define _di_fll_program_print_help_usage_
 #define _di_fll_program_print_signal_received_
 #define _di_fll_program_print_version_
index 8539e74..50f98fd 100644 (file)
 #define _di_fll_program_print_error_pipe_missing_content_
 #define _di_fll_program_print_error_pipe_object_without_content_
 //#define _di_fll_program_print_help_header_
+//#define _di_fll_program_print_help_operations_
 //#define _di_fll_program_print_help_option_
 //#define _di_fll_program_print_help_option_long_
 //#define _di_fll_program_print_help_option_other_
 //#define _di_fll_program_print_help_option_standard_
+//#define _di_fll_program_print_help_special_options_
 //#define _di_fll_program_print_help_usage_
 //#define _di_fll_program_print_signal_received_
 //#define _di_fll_program_print_version_
index 9ddcc62..b0d0463 100644 (file)
@@ -560,6 +560,9 @@ extern "C" {
  * The f_console_standard_parameter_last_e is not a parameter.
  * f_console_standard_parameter_last_e represents the end of the enumeration.
  * Use f_console_standard_parameter_last_e as the starting enum for any custom project.
+ *
+ * This also defines f_console_parameter_state_type_total_d to represent the total, not including the parameter last.
+ * This is provided so that this total can be use by the pre-processor in macro mathematical operations.
  */
 #ifndef _di_f_console_parameter_state_type_e_
   enum {
@@ -578,6 +581,8 @@ extern "C" {
     f_console_standard_parameter_line_last_no_e,
     f_console_standard_parameter_last_e,
   }; // enum
+
+  #define f_console_parameter_state_type_total_d 13
 #endif // _di_f_console_standard_parameter_e_
 
 /**
index b53a6b4..0b4663b 100644 (file)
@@ -147,20 +147,75 @@ extern "C" {
 #endif // _di_f_string_ascii_s_
 
 #ifndef _di_f_string_format_s_
+  const f_string_static_t f_string_format_d_double_s           = macro_f_string_static_t_initialize_1(F_string_format_d_double_s, 0, F_string_format_d_double_s_length);
+  const f_string_static_t f_string_format_d_single_s           = macro_f_string_static_t_initialize_1(F_string_format_d_single_s, 0, F_string_format_d_single_s_length);
+  const f_string_static_t f_string_format_D_double_s           = macro_f_string_static_t_initialize_1(F_string_format_D_double_s, 0, F_string_format_D_double_s_length);
+  const f_string_static_t f_string_format_D_single_s           = macro_f_string_static_t_initialize_1(F_string_format_D_single_s, 0, F_string_format_D_single_s_length);
+  const f_string_static_t f_string_format_i_double_s           = macro_f_string_static_t_initialize_1(F_string_format_i_double_s, 0, F_string_format_i_double_s_length);
+  const f_string_static_t f_string_format_i_single_s           = macro_f_string_static_t_initialize_1(F_string_format_i_single_s, 0, F_string_format_i_single_s_length);
+  const f_string_static_t f_string_format_q_double_s           = macro_f_string_static_t_initialize_1(F_string_format_q_double_s, 0, F_string_format_q_double_s_length);
+  const f_string_static_t f_string_format_q_range_double_s     = macro_f_string_static_t_initialize_1(F_string_format_q_range_double_s, 0, F_string_format_q_range_double_s_length);
+  const f_string_static_t f_string_format_q_range_single_s     = macro_f_string_static_t_initialize_1(F_string_format_q_range_single_s, 0, F_string_format_q_range_single_s_length);
+  const f_string_static_t f_string_format_q_single_s           = macro_f_string_static_t_initialize_1(F_string_format_q_single_s, 0, F_string_format_q_single_s_length);
   const f_string_static_t f_string_format_Q_double_s           = macro_f_string_static_t_initialize_1(F_string_format_Q_double_s, 0, F_string_format_Q_double_s_length);
   const f_string_static_t f_string_format_Q_range_double_s     = macro_f_string_static_t_initialize_1(F_string_format_Q_range_double_s, 0, F_string_format_Q_range_double_s_length);
   const f_string_static_t f_string_format_Q_range_single_s     = macro_f_string_static_t_initialize_1(F_string_format_Q_range_single_s, 0, F_string_format_Q_range_single_s_length);
   const f_string_static_t f_string_format_Q_single_s           = macro_f_string_static_t_initialize_1(F_string_format_Q_single_s, 0, F_string_format_Q_single_s_length);
-  const f_string_static_t f_string_format_QQ_double_s          = macro_f_string_static_t_initialize_1(F_string_format_QQ_double_s, 0, F_string_format_QQ_double_s_length);
-  const f_string_static_t f_string_format_QQ_single_s          = macro_f_string_static_t_initialize_1(F_string_format_QQ_single_s, 0, F_string_format_QQ_single_s_length);
   const f_string_static_t f_string_format_r_double_s           = macro_f_string_static_t_initialize_1(F_string_format_r_double_s, 0, F_string_format_r_double_s_length);
+  const f_string_static_t f_string_format_r_range_double_s     = macro_f_string_static_t_initialize_1(F_string_format_r_range_double_s, 0, F_string_format_r_range_double_s_length);
+  const f_string_static_t f_string_format_r_range_single_s     = macro_f_string_static_t_initialize_1(F_string_format_r_range_single_s, 0, F_string_format_r_range_single_s_length);
   const f_string_static_t f_string_format_r_single_s           = macro_f_string_static_t_initialize_1(F_string_format_r_single_s, 0, F_string_format_r_single_s_length);
+  const f_string_static_t f_string_format_R_double_s           = macro_f_string_static_t_initialize_1(F_string_format_R_double_s, 0, F_string_format_R_double_s_length);
+  const f_string_static_t f_string_format_R_range_double_s     = macro_f_string_static_t_initialize_1(F_string_format_R_range_double_s, 0, F_string_format_R_range_double_s_length);
+  const f_string_static_t f_string_format_R_range_single_s     = macro_f_string_static_t_initialize_1(F_string_format_R_range_single_s, 0, F_string_format_R_range_single_s_length);
+  const f_string_static_t f_string_format_R_single_s           = macro_f_string_static_t_initialize_1(F_string_format_R_single_s, 0, F_string_format_R_single_s_length);
+  const f_string_static_t f_string_format_s_double_s           = macro_f_string_static_t_initialize_1(F_string_format_s_double_s, 0, F_string_format_s_double_s_length);
+  const f_string_static_t f_string_format_s_single_s           = macro_f_string_static_t_initialize_1(F_string_format_s_single_s, 0, F_string_format_s_single_s_length);
+  const f_string_static_t f_string_format_S_double_s           = macro_f_string_static_t_initialize_1(F_string_format_S_double_s, 0, F_string_format_S_double_s_length);
+  const f_string_static_t f_string_format_S_single_s           = macro_f_string_static_t_initialize_1(F_string_format_S_single_s, 0, F_string_format_S_single_s_length);
+  const f_string_static_t f_string_format_u_double_s           = macro_f_string_static_t_initialize_1(F_string_format_u_double_s, 0, F_string_format_u_double_s_length);
+  const f_string_static_t f_string_format_u_single_s           = macro_f_string_static_t_initialize_1(F_string_format_u_single_s, 0, F_string_format_u_single_s_length);
+  const f_string_static_t f_string_format_z_double_s           = macro_f_string_static_t_initialize_1(F_string_format_z_double_s, 0, F_string_format_z_double_s_length);
+  const f_string_static_t f_string_format_z_single_s           = macro_f_string_static_t_initialize_1(F_string_format_z_single_s, 0, F_string_format_z_single_s_length);
+  const f_string_static_t f_string_format_Z_double_s           = macro_f_string_static_t_initialize_1(F_string_format_Z_double_s, 0, F_string_format_Z_double_s_length);
+  const f_string_static_t f_string_format_Z_single_s           = macro_f_string_static_t_initialize_1(F_string_format_Z_single_s, 0, F_string_format_Z_single_s_length);
+  const f_string_static_t f_string_format_dl_double_s          = macro_f_string_static_t_initialize_1(F_string_format_dl_double_s, 0, F_string_format_dl_double_s_length);
+  const f_string_static_t f_string_format_dl_single_s          = macro_f_string_static_t_initialize_1(F_string_format_dl_single_s, 0, F_string_format_dl_single_s_length);
+  const f_string_static_t f_string_format_DL_double_s          = macro_f_string_static_t_initialize_1(F_string_format_DL_double_s, 0, F_string_format_DL_double_s_length);
+  const f_string_static_t f_string_format_DL_single_s          = macro_f_string_static_t_initialize_1(F_string_format_DL_single_s, 0, F_string_format_DL_single_s_length);
+  const f_string_static_t f_string_format_ii_double_s          = macro_f_string_static_t_initialize_1(F_string_format_ii_double_s, 0, F_string_format_ii_double_s_length);
+  const f_string_static_t f_string_format_ii_single_s          = macro_f_string_static_t_initialize_1(F_string_format_ii_single_s, 0, F_string_format_ii_single_s_length);
+  const f_string_static_t f_string_format_il_double_s          = macro_f_string_static_t_initialize_1(F_string_format_il_double_s, 0, F_string_format_il_double_s_length);
+  const f_string_static_t f_string_format_il_single_s          = macro_f_string_static_t_initialize_1(F_string_format_il_single_s, 0, F_string_format_il_single_s_length);
+  const f_string_static_t f_string_format_in_double_s          = macro_f_string_static_t_initialize_1(F_string_format_in_double_s, 0, F_string_format_in_double_s_length);
+  const f_string_static_t f_string_format_in_single_s          = macro_f_string_static_t_initialize_1(F_string_format_in_single_s, 0, F_string_format_in_single_s_length);
+  const f_string_static_t f_string_format_QQ_double_s          = macro_f_string_static_t_initialize_1(F_string_format_QQ_double_s, 0, F_string_format_QQ_double_s_length);
+  const f_string_static_t f_string_format_QQ_single_s          = macro_f_string_static_t_initialize_1(F_string_format_QQ_single_s, 0, F_string_format_QQ_single_s_length);
   const f_string_static_t f_string_format_rr_double_s          = macro_f_string_static_t_initialize_1(F_string_format_rr_double_s, 0, F_string_format_rr_double_s_length);
   const f_string_static_t f_string_format_rr_single_s          = macro_f_string_static_t_initialize_1(F_string_format_rr_single_s, 0, F_string_format_rr_single_s_length);
-  const f_string_static_t f_string_format_sentence_end_s       = macro_f_string_static_t_initialize_1(F_string_format_sentence_end_s, 0, F_string_format_sentence_end_s_length);
-  const f_string_static_t f_string_format_sentence_end_quote_s = macro_f_string_static_t_initialize_1(F_string_format_sentence_end_quote_s, 0, F_string_format_sentence_end_quote_s_length);
+  const f_string_static_t f_string_format_RR_double_s          = macro_f_string_static_t_initialize_1(F_string_format_RR_double_s, 0, F_string_format_RR_double_s_length);
+  const f_string_static_t f_string_format_RR_single_s          = macro_f_string_static_t_initialize_1(F_string_format_RR_single_s, 0, F_string_format_RR_single_s_length);
+  const f_string_static_t f_string_format_ss_double_s          = macro_f_string_static_t_initialize_1(F_string_format_ss_double_s, 0, F_string_format_ss_double_s_length);
+  const f_string_static_t f_string_format_ss_single_s          = macro_f_string_static_t_initialize_1(F_string_format_ss_single_s, 0, F_string_format_ss_single_s_length);
+  const f_string_static_t f_string_format_SS_double_s          = macro_f_string_static_t_initialize_1(F_string_format_SS_double_s, 0, F_string_format_SS_double_s_length);
+  const f_string_static_t f_string_format_SS_single_s          = macro_f_string_static_t_initialize_1(F_string_format_SS_single_s, 0, F_string_format_SS_single_s_length);
+  const f_string_static_t f_string_format_ui_double_s          = macro_f_string_static_t_initialize_1(F_string_format_ui_double_s, 0, F_string_format_ui_double_s_length);
+  const f_string_static_t f_string_format_ui_single_s          = macro_f_string_static_t_initialize_1(F_string_format_ui_single_s, 0, F_string_format_ui_single_s_length);
   const f_string_static_t f_string_format_ul_double_s          = macro_f_string_static_t_initialize_1(F_string_format_ul_double_s, 0, F_string_format_ul_double_s_length);
   const f_string_static_t f_string_format_ul_single_s          = macro_f_string_static_t_initialize_1(F_string_format_ul_single_s, 0, F_string_format_ul_single_s_length);
+  const f_string_static_t f_string_format_un_double_s          = macro_f_string_static_t_initialize_1(F_string_format_un_double_s, 0, F_string_format_un_double_s_length);
+  const f_string_static_t f_string_format_un_single_s          = macro_f_string_static_t_initialize_1(F_string_format_un_single_s, 0, F_string_format_un_single_s_length);
+  const f_string_static_t f_string_format_iii_double_s         = macro_f_string_static_t_initialize_1(F_string_format_iii_double_s, 0, F_string_format_iii_double_s_length);
+  const f_string_static_t f_string_format_iii_single_s         = macro_f_string_static_t_initialize_1(F_string_format_iii_single_s, 0, F_string_format_iii_single_s_length);
+  const f_string_static_t f_string_format_ill_double_s         = macro_f_string_static_t_initialize_1(F_string_format_ill_double_s, 0, F_string_format_ill_double_s_length);
+  const f_string_static_t f_string_format_ill_single_s         = macro_f_string_static_t_initialize_1(F_string_format_ill_single_s, 0, F_string_format_ill_single_s_length);
+  const f_string_static_t f_string_format_uii_double_s         = macro_f_string_static_t_initialize_1(F_string_format_uii_double_s, 0, F_string_format_uii_double_s_length);
+  const f_string_static_t f_string_format_uii_single_s         = macro_f_string_static_t_initialize_1(F_string_format_uii_single_s, 0, F_string_format_uii_single_s_length);
+  const f_string_static_t f_string_format_ull_double_s         = macro_f_string_static_t_initialize_1(F_string_format_ull_double_s, 0, F_string_format_ull_double_s_length);
+  const f_string_static_t f_string_format_ull_single_s         = macro_f_string_static_t_initialize_1(F_string_format_ull_single_s, 0, F_string_format_ull_single_s_length);
+
+  const f_string_static_t f_string_format_sentence_end_s       = macro_f_string_static_t_initialize_1(F_string_format_sentence_end_s, 0, F_string_format_sentence_end_s_length);
+  const f_string_static_t f_string_format_sentence_end_quote_s = macro_f_string_static_t_initialize_1(F_string_format_sentence_end_quote_s, 0, F_string_format_sentence_end_quote_s_length);
 #endif // _di_f_string_format_s_
 
 #ifdef __cplusplus
index adf8c28..24c46fa 100644 (file)
@@ -499,50 +499,215 @@ extern "C" {
  * Provide a static strings focusing on the commonly used print format strings.
  */
 #ifndef _di_f_string_format_s_
-  #define F_string_format_Q_double_s           "%[%[%Q%]%]"
-  #define F_string_format_Q_range_double_s     "%[%[%/Q%]%]"
-  #define F_string_format_Q_range_single_s     "%[%/Q%]"
-  #define F_string_format_Q_single_s           "%[%Q%]"
-  #define F_string_format_QQ_double_s          "%[%[%Q%Q%]%]"
-  #define F_string_format_QQ_single_s          "%[%Q%Q%]"
-  #define F_string_format_r_double_s           "%[%[%r%]%]"
-  #define F_string_format_r_single_s           "%[%r%]"
-  #define F_string_format_rr_double_s          "%[%[%r%r%]%]"
-  #define F_string_format_rr_single_s          "%[%r%r%]"
+  #define F_string_format_d_double_s       "%[%[%d%]%]"
+  #define F_string_format_d_single_s       "%[%d%]"
+  #define F_string_format_D_double_s       "%[%[%D%]%]"
+  #define F_string_format_D_single_s       "%[%D%]"
+  #define F_string_format_i_double_s       "%[%[%i%]%]"
+  #define F_string_format_i_single_s       "%[%i%]"
+  #define F_string_format_q_double_s       "%[%[%q%]%]"
+  #define F_string_format_q_range_double_s "%[%[%/q%]%]"
+  #define F_string_format_q_range_single_s "%[%/q%]"
+  #define F_string_format_q_single_s       "%[%q%]"
+  #define F_string_format_Q_double_s       "%[%[%Q%]%]"
+  #define F_string_format_Q_range_double_s "%[%[%/Q%]%]"
+  #define F_string_format_Q_range_single_s "%[%/Q%]"
+  #define F_string_format_Q_single_s       "%[%Q%]"
+  #define F_string_format_r_double_s       "%[%[%r%]%]"
+  #define F_string_format_r_range_double_s "%[%[%/r%]%]"
+  #define F_string_format_r_range_single_s "%[%/r%]"
+  #define F_string_format_r_single_s       "%[%r%]"
+  #define F_string_format_R_double_s       "%[%[%R%]%]"
+  #define F_string_format_R_range_double_s "%[%[%/R%]%]"
+  #define F_string_format_R_range_single_s "%[%/R%]"
+  #define F_string_format_R_single_s       "%[%R%]"
+  #define F_string_format_s_double_s       "%[%[%s%]%]"
+  #define F_string_format_s_single_s       "%[%s%]"
+  #define F_string_format_S_double_s       "%[%[%S%]%]"
+  #define F_string_format_S_single_s       "%[%S%]"
+  #define F_string_format_u_double_s       "%[%[%u%]%]"
+  #define F_string_format_u_single_s       "%[%u%]"
+  #define F_string_format_z_double_s       "%[%[%u%]%]"
+  #define F_string_format_z_single_s       "%[%u%]"
+  #define F_string_format_Z_double_s       "%[%[%u%]%]"
+  #define F_string_format_Z_single_s       "%[%u%]"
+  #define F_string_format_dl_double_s      "%[%[%dl%]%]"
+  #define F_string_format_dl_single_s      "%[%dl%]"
+  #define F_string_format_DL_double_s      "%[%[%DL%]%]"
+  #define F_string_format_DL_single_s      "%[%DL%]"
+  #define F_string_format_ii_double_s      "%[%[%ii%]%]"
+  #define F_string_format_ii_single_s      "%[%ii%]"
+  #define F_string_format_il_double_s      "%[%[%il%]%]"
+  #define F_string_format_il_single_s      "%[%il%]"
+  #define F_string_format_in_double_s      "%[%[%in%]%]"
+  #define F_string_format_in_single_s      "%[%in%]"
+  #define F_string_format_QQ_double_s      "%[%[%Q%Q%]%]"
+  #define F_string_format_QQ_single_s      "%[%Q%Q%]"
+  #define F_string_format_rr_double_s      "%[%[%r%r%]%]"
+  #define F_string_format_rr_single_s      "%[%r%r%]"
+  #define F_string_format_RR_double_s      "%[%[%R%R%]%]"
+  #define F_string_format_RR_single_s      "%[%R%R%]"
+  #define F_string_format_ss_double_s      "%[%[%s%s%]%]"
+  #define F_string_format_ss_single_s      "%[%s%s%]"
+  #define F_string_format_SS_double_s      "%[%[%S%S%]%]"
+  #define F_string_format_SS_single_s      "%[%S%S%]"
+  #define F_string_format_ui_double_s      "%[%[%ui%]%]"
+  #define F_string_format_ui_single_s      "%[%ui%]"
+  #define F_string_format_ul_double_s      "%[%[%ul%]%]"
+  #define F_string_format_ul_single_s      "%[%ul%]"
+  #define F_string_format_un_double_s      "%[%[%un%]%]"
+  #define F_string_format_un_single_s      "%[%un%]"
+  #define F_string_format_iii_double_s     "%[%[%iii%]%]"
+  #define F_string_format_iii_single_s     "%[%iii%]"
+  #define F_string_format_ill_double_s     "%[%[%ill%]%]"
+  #define F_string_format_ill_single_s     "%[%ill%]"
+  #define F_string_format_uii_double_s     "%[%[%uii%]%]"
+  #define F_string_format_uii_single_s     "%[%uii%]"
+  #define F_string_format_ull_double_s     "%[%[%ull%]%]"
+  #define F_string_format_ull_single_s     "%[%ull%]"
+
   #define F_string_format_sentence_end_s       "%[.%]%r"
   #define F_string_format_sentence_end_quote_s "%['.%]%r"
-  #define F_string_format_ul_double_s          "%[%[%ul%]%]"
-  #define F_string_format_ul_single_s          "%[%ul%]"
-
-  #define F_string_format_Q_double_s_length           10
-  #define F_string_format_Q_range_double_s_length     11
-  #define F_string_format_Q_range_single_s_length     7
-  #define F_string_format_Q_single_s_length           6
-  #define F_string_format_QQ_double_s_length          12
-  #define F_string_format_QQ_single_s_length          8
-  #define F_string_format_r_double_s_length           10
-  #define F_string_format_r_single_s_length           6
-  #define F_string_format_rr_double_s_length          12
-  #define F_string_format_rr_single_s_length          8
+
+  #define F_string_format_d_single_s_length       10
+  #define F_string_format_d_double_s_length       6
+  #define F_string_format_D_single_s_length       10
+  #define F_string_format_D_double_s_length       6
+  #define F_string_format_i_single_s_length       10
+  #define F_string_format_i_double_s_length       6
+  #define F_string_format_q_double_s_length       10
+  #define F_string_format_q_range_double_s_length 11
+  #define F_string_format_q_range_single_s_length 7
+  #define F_string_format_q_single_s_length       6
+  #define F_string_format_Q_double_s_length       10
+  #define F_string_format_Q_range_double_s_length 11
+  #define F_string_format_Q_range_single_s_length 7
+  #define F_string_format_Q_single_s_length       6
+  #define F_string_format_r_double_s_length       10
+  #define F_string_format_r_range_double_s_length 11
+  #define F_string_format_r_range_single_s_length 7
+  #define F_string_format_r_single_s_length       6
+  #define F_string_format_R_double_s_length       10
+  #define F_string_format_R_range_double_s_length 11
+  #define F_string_format_R_range_single_s_length 7
+  #define F_string_format_R_single_s_length       6
+  #define F_string_format_s_single_s_length       10
+  #define F_string_format_s_double_s_length       6
+  #define F_string_format_S_single_s_length       10
+  #define F_string_format_S_double_s_length       6
+  #define F_string_format_u_single_s_length       10
+  #define F_string_format_u_double_s_length       6
+  #define F_string_format_z_single_s_length       10
+  #define F_string_format_z_double_s_length       6
+  #define F_string_format_Z_single_s_length       10
+  #define F_string_format_Z_double_s_length       6
+  #define F_string_format_dl_single_s_length      11
+  #define F_string_format_dl_double_s_length      7
+  #define F_string_format_DL_single_s_length      11
+  #define F_string_format_DL_double_s_length      7
+  #define F_string_format_ii_single_s_length      11
+  #define F_string_format_ii_double_s_length      7
+  #define F_string_format_il_single_s_length      11
+  #define F_string_format_il_double_s_length      7
+  #define F_string_format_in_single_s_length      11
+  #define F_string_format_in_double_s_length      7
+  #define F_string_format_QQ_double_s_length      12
+  #define F_string_format_QQ_single_s_length      8
+  #define F_string_format_rr_double_s_length      12
+  #define F_string_format_rr_single_s_length      8
+  #define F_string_format_RR_double_s_length      12
+  #define F_string_format_RR_single_s_length      8
+  #define F_string_format_ss_single_s_length      12
+  #define F_string_format_ss_double_s_length      8
+  #define F_string_format_SS_single_s_length      12
+  #define F_string_format_SS_double_s_length      8
+  #define F_string_format_ui_single_s_length      11
+  #define F_string_format_ui_double_s_length      7
+  #define F_string_format_ul_single_s_length      11
+  #define F_string_format_ul_double_s_length      7
+  #define F_string_format_un_single_s_length      11
+  #define F_string_format_un_double_s_length      7
+  #define F_string_format_iii_single_s_length     12
+  #define F_string_format_iii_double_s_length     8
+  #define F_string_format_ill_single_s_length     12
+  #define F_string_format_ill_double_s_length     8
+  #define F_string_format_uii_single_s_length     12
+  #define F_string_format_uii_double_s_length     8
+  #define F_string_format_ull_single_s_length     12
+  #define F_string_format_ull_double_s_length     8
+
   #define F_string_format_sentence_end_s_length       7
   #define F_string_format_sentence_end_quote_s_length 6
-  #define F_string_format_ul_single_s_length          11
-  #define F_string_format_ul_double_s_length          7
 
+  extern const f_string_static_t f_string_format_d_double_s;
+  extern const f_string_static_t f_string_format_d_single_s;
+  extern const f_string_static_t f_string_format_D_double_s;
+  extern const f_string_static_t f_string_format_D_single_s;
+  extern const f_string_static_t f_string_format_i_double_s;
+  extern const f_string_static_t f_string_format_i_single_s;
+  extern const f_string_static_t f_string_format_q_double_s;
+  extern const f_string_static_t f_string_format_q_range_double_s;
+  extern const f_string_static_t f_string_format_q_range_single_s;
+  extern const f_string_static_t f_string_format_q_single_s;
   extern const f_string_static_t f_string_format_Q_double_s;
   extern const f_string_static_t f_string_format_Q_range_double_s;
   extern const f_string_static_t f_string_format_Q_range_single_s;
   extern const f_string_static_t f_string_format_Q_single_s;
-  extern const f_string_static_t f_string_format_QQ_double_s;
-  extern const f_string_static_t f_string_format_QQ_single_s;
   extern const f_string_static_t f_string_format_r_double_s;
+  extern const f_string_static_t f_string_format_r_range_double_s;
+  extern const f_string_static_t f_string_format_r_range_single_s;
   extern const f_string_static_t f_string_format_r_single_s;
+  extern const f_string_static_t f_string_format_R_double_s;
+  extern const f_string_static_t f_string_format_R_range_double_s;
+  extern const f_string_static_t f_string_format_R_range_single_s;
+  extern const f_string_static_t f_string_format_R_single_s;
+  extern const f_string_static_t f_string_format_s_double_s;
+  extern const f_string_static_t f_string_format_s_single_s;
+  extern const f_string_static_t f_string_format_S_double_s;
+  extern const f_string_static_t f_string_format_S_single_s;
+  extern const f_string_static_t f_string_format_u_double_s;
+  extern const f_string_static_t f_string_format_u_single_s;
+  extern const f_string_static_t f_string_format_z_double_s;
+  extern const f_string_static_t f_string_format_z_single_s;
+  extern const f_string_static_t f_string_format_Z_double_s;
+  extern const f_string_static_t f_string_format_Z_single_s;
+  extern const f_string_static_t f_string_format_dl_double_s;
+  extern const f_string_static_t f_string_format_dl_single_s;
+  extern const f_string_static_t f_string_format_DL_double_s;
+  extern const f_string_static_t f_string_format_DL_single_s;
+  extern const f_string_static_t f_string_format_ii_double_s;
+  extern const f_string_static_t f_string_format_ii_single_s;
+  extern const f_string_static_t f_string_format_il_double_s;
+  extern const f_string_static_t f_string_format_il_single_s;
+  extern const f_string_static_t f_string_format_in_double_s;
+  extern const f_string_static_t f_string_format_in_single_s;
+  extern const f_string_static_t f_string_format_QQ_double_s;
+  extern const f_string_static_t f_string_format_QQ_single_s;
   extern const f_string_static_t f_string_format_rr_double_s;
   extern const f_string_static_t f_string_format_rr_single_s;
-  extern const f_string_static_t f_string_format_sentence_end_s;
-  extern const f_string_static_t f_string_format_sentence_end_quote_s;
+  extern const f_string_static_t f_string_format_RR_double_s;
+  extern const f_string_static_t f_string_format_RR_single_s;
+  extern const f_string_static_t f_string_format_ss_double_s;
+  extern const f_string_static_t f_string_format_ss_single_s;
+  extern const f_string_static_t f_string_format_SS_double_s;
+  extern const f_string_static_t f_string_format_SS_single_s;
+  extern const f_string_static_t f_string_format_ui_double_s;
+  extern const f_string_static_t f_string_format_ui_single_s;
   extern const f_string_static_t f_string_format_ul_double_s;
   extern const f_string_static_t f_string_format_ul_single_s;
+  extern const f_string_static_t f_string_format_un_double_s;
+  extern const f_string_static_t f_string_format_un_single_s;
+  extern const f_string_static_t f_string_format_iii_double_s;
+  extern const f_string_static_t f_string_format_iii_single_s;
+  extern const f_string_static_t f_string_format_ill_double_s;
+  extern const f_string_static_t f_string_format_ill_single_s;
+  extern const f_string_static_t f_string_format_uii_double_s;
+  extern const f_string_static_t f_string_format_uii_single_s;
+  extern const f_string_static_t f_string_format_ull_double_s;
+  extern const f_string_static_t f_string_format_ull_single_s;
+
+  extern const f_string_static_t f_string_format_sentence_end_s;
+  extern const f_string_static_t f_string_format_sentence_end_quote_s;
 #endif // _di_f_string_format_s_
 
 /**
index b5224cd..7ac76c8 100644 (file)
@@ -561,6 +561,18 @@ extern "C" {
   }
 #endif // _di_fll_program_print_help_header_
 
+#ifndef _di_fll_program_print_help_operations_
+  f_status_t fll_program_print_help_operations(fl_print_t * const print) {
+    #ifndef _di_level_2_parameter_checking_
+      if (!print) return F_status_set_error(F_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    fl_print_format(" %[Operations:%]%r", print->to, print->set->important, print->set->important, f_string_eol_s);
+
+    return F_okay;
+  }
+#endif // _di_fll_program_print_help_operations_
+
 #ifndef _di_fll_program_print_help_option_
   f_status_t fll_program_print_help_option(fl_print_t * const print, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description) {
     #ifndef _di_level_2_parameter_checking_
@@ -619,6 +631,18 @@ extern "C" {
   }
 #endif // _di_fll_program_print_help_option_other_
 
+#ifndef _di_fll_program_print_help_special_options_
+  f_status_t fll_program_print_help_special_options(fl_print_t * const print) {
+    #ifndef _di_level_2_parameter_checking_
+      if (!print) return F_status_set_error(F_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    fl_print_format(" %[Special Options:%]%r", print->to, print->set->important, print->set->important, f_string_eol_s);
+
+    return F_okay;
+  }
+#endif // _di_fll_program_print_help_special_options_
+
 #ifndef _di_fll_program_print_help_usage_
   f_status_t fll_program_print_help_usage(fl_print_t * const print, const f_string_static_t name, const f_string_static_t parameters) {
     #ifndef _di_level_2_parameter_checking_
@@ -656,7 +680,7 @@ extern "C" {
     f_file_stream_flush(print->to);
 
     fl_print_format("%]%[Received signal code %]", print->to, print->set->reset, print->set->warning, print->set->warning);
-    fl_print_format("%[%u%]", print->to, print->set->notable, signal, print->set->notable);
+    fl_print_format(f_string_format_u_single_s.string, print->to, print->set->notable, signal, print->set->notable);
     fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->warning, print->set->warning, f_string_eol_s);
 
     f_file_stream_unlock(print->to);
index c6e003e..41cbdef 100644 (file)
@@ -813,6 +813,28 @@ extern "C" {
   extern f_status_t fll_program_print_help_header(fl_print_t * const print, const f_string_static_t name, const f_string_static_t version);
 #endif // _di_fll_program_print_help_header_
 
+/**
+ * Print standard help operations.
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ *   The output structure to print to.
+ *   This uses but does not lock or unlock file stream.
+ *   This requires print.set to be non-NULL.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_help_operations_
+  extern f_status_t fll_program_print_help_operations(fl_print_t * const print);
+#endif // _di_fll_program_print_help_operations_
+
 /**
  * Print standard help option.
  *
@@ -923,6 +945,28 @@ extern "C" {
   extern f_status_t fll_program_print_help_option_standard(fl_print_t * const print);
 #endif // _di_fll_program_print_help_option_standard_
 
+/**
+ * Print standard help special options.
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ *   The output structure to print to.
+ *   This uses but does not lock or unlock file stream.
+ *   This requires print.set to be non-NULL.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_help_special_options_
+  extern f_status_t fll_program_print_help_special_options(fl_print_t * const print);
+#endif // _di_fll_program_print_help_special_options_
+
 /**
  * Print standard help usage.
  *
index fc1af07..ce24620 100644 (file)
@@ -23,7 +23,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (byte_dump_main_flag_help_e | byte_dump_main_flag_version_e | byte_dump_main_flag_copyright_e)) {
+    if (main->setting.flag & byte_dump_main_flag_version_copyright_help_e) {
       if (main->setting.flag & byte_dump_main_flag_help_e) {
         byte_dump_print_message_help(&main->program.message);
       }
index b102980..87c33af 100644 (file)
@@ -60,37 +60,39 @@ extern "C" {
  * Flags passed to the main function or program.
  *
  * byte_dump_main_flag_*_e:
- *   - none:        No flags set.
- *   - classic:     Classic is specified.
- *   - copyright:   Print the copyright.
- *   - first:       The first position is specified.
- *   - help:        Print help.
- *   - last:        The last position is specified.
- *   - placeholder: Placeholder is specified.
- *   - pipe:        Use the input pipe.
- *   - print_first: When set, print new line to message output on program begin after loading settings.
- *   - print_last:  When set, print new line to message output on program end.
- *   - text:        Text is specified.
- *   - unicode:     Unicode is specified.
- *   - version:     Print version.
- *   - wide:        Wide option is specified for printing wide.
+ *   - none:                   No flags set.
+ *   - classic:                Classic is specified.
+ *   - copyright:              Print the copyright.
+ *   - first:                  The first position is specified.
+ *   - help:                   Print help.
+ *   - last:                   The last position is specified.
+ *   - placeholder:            Placeholder is specified.
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - text:                   Text is specified.
+ *   - unicode:                Unicode is specified.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
+ *   - wide:                   Wide option is specified for printing wide.
  */
 #ifndef _di_byte_dump_main_flag_e_
   enum {
-    byte_dump_main_flag_none_e        = 0x0,
-    byte_dump_main_flag_classic_e     = 0x1,
-    byte_dump_main_flag_copyright_e   = 0x2,
-    byte_dump_main_flag_first_e       = 0x4,
-    byte_dump_main_flag_help_e        = 0x8,
-    byte_dump_main_flag_last_e        = 0x10,
-    byte_dump_main_flag_pipe_e        = 0x20,
-    byte_dump_main_flag_placeholder_e = 0x40,
-    byte_dump_main_flag_print_first_e = 0x80,
-    byte_dump_main_flag_print_last_e  = 0x100,
-    byte_dump_main_flag_text_e        = 0x200,
-    byte_dump_main_flag_unicode_e     = 0x400,
-    byte_dump_main_flag_version_e     = 0x800,
-    byte_dump_main_flag_wide_e        = 0x1000,
+    byte_dump_main_flag_none_e                   = 0x0,
+    byte_dump_main_flag_classic_e                = 0x1,
+    byte_dump_main_flag_copyright_e              = 0x2,
+    byte_dump_main_flag_first_e                  = 0x4,
+    byte_dump_main_flag_help_e                   = 0x8,
+    byte_dump_main_flag_last_e                   = 0x10,
+    byte_dump_main_flag_pipe_e                   = 0x20,
+    byte_dump_main_flag_placeholder_e            = 0x40,
+    byte_dump_main_flag_print_first_e            = 0x80,
+    byte_dump_main_flag_print_last_e             = 0x100,
+    byte_dump_main_flag_text_e                   = 0x200,
+    byte_dump_main_flag_unicode_e                = 0x400,
+    byte_dump_main_flag_version_e                = 0x800,
+    byte_dump_main_flag_version_copyright_help_e = 0x80a,
+    byte_dump_main_flag_wide_e                   = 0x1000,
   }; // enum
 #endif // _di_byte_dump_main_flag_e_
 
@@ -166,7 +168,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_5(byte_dump_long_classic_s, 0, f_console_flag_normal_e), \
     }
 
-  #define byte_dump_parameter_total_d 29
+  #define byte_dump_parameter_total_d (f_console_parameter_state_type_total_d + 16)
 #endif // _di_byte_dump_parameter_e_
 
 /**
index 8134849..966ceb8 100644 (file)
@@ -70,7 +70,8 @@ extern "C" {
 
     fl_print_format("%[%Qread() failed for '%]", print->to, print->set->error, print->prefix, print->set->error);
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name.used ? name : f_string_ascii_minus_s, print->set->notable);
-    fl_print_format("%['.%]%r%r", print->to, print->set->error, print->set->error, f_string_eol_s, f_string_eol_s);
+    fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
+    f_print_dynamic_raw(f_string_eol_s, print->to);
 
     f_file_stream_unlock(print->to);
 
@@ -89,11 +90,11 @@ extern "C" {
     f_file_stream_lock(print->to);
 
     fl_print_format("%[%QThe value '%]", print->to, print->set->error, print->prefix, print->set->error);
-    fl_print_format("%[%ul%]", print->to, print->set->notable, main->setting.first, print->set->notable);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->set->notable, main->setting.first, print->set->notable);
     fl_print_format("%[' for the parameter '%]", print->to, print->set->error, print->set->error);
     fl_print_format(f_string_format_rr_single_s.string, print->to, print->set->notable, f_console_symbol_long_normal_s, byte_dump_long_first_s, print->set->notable);
     fl_print_format("%[' cannot be greater than the value '%]", print->to, print->set->error, print->set->error);
-    fl_print_format("%[%ul%]", print->to, print->set->notable, main->setting.last, print->set->notable);
+    fl_print_format(f_string_format_ul_single_s.string", print->to, print->set->notable, main->setting.last, print->set->notable);
     fl_print_format("%[' for the parameter '%]", print->to, print->set->error, print->set->error);
     fl_print_format(f_string_format_rr_single_s.string, print->to, print->set->notable, f_console_symbol_long_normal_s, byte_dump_long_last_s, print->set->notable);
     fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
index 002cacd..07abea0 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
  *   The output structure to print to.
  *
  *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
  *
  * @return
  *   F_okay on success.
index 580aeea..f252cac 100644 (file)
@@ -39,7 +39,9 @@ extern "C" {
     fll_program_print_help_option(print, byte_dump_short_wide_s, byte_dump_long_wide_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "       Use wide display, resulting in 2*width allowing for space for wide characters in the text columns.");
     fll_program_print_help_option(print, byte_dump_short_width_s, byte_dump_long_width_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "      Set number of columns of Bytes to display.");
 
-    fl_print_format("%r %[Special Options:%] %r", print->to, f_string_eol_s, print->set->important, print->set->important, f_string_eol_s);
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    fll_program_print_help_special_options(print);
 
     fll_program_print_help_option_long(print, byte_dump_long_normal_s, f_console_symbol_long_normal_s, " Display UTF-8 symbols for ASCII control codes.");
     fll_program_print_help_option_long(print, byte_dump_long_simple_s, f_console_symbol_long_normal_s, " Display spaces for ASCII control codes.");
index f68baf8..6d8d4c9 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_byte_dump_thread_signal_) && !defined(_di_thread_support_)
   void * byte_dump_thread_signal(void * const main) {
 
index 90d0999..5da619b 100644 (file)
@@ -82,26 +82,28 @@ extern "C" {
  * Flags passed to the main function or program.
  *
  * control_main_flag_*_e:
- *   - none:          No flags set.
- *   - copyright:     Print copyright.
- *   - header:        Enable printing of headers.
- *   - help:          Print help.
- *   - pipe:          Use the input pipe.
- *   - print_first:   When set, print new line to message output on program begin after loading settings.
- *   - print_last:    When set, print new line to message output on program end.
- *   - return:        The parameter is specified.
- *   - version:       Print version.
+ *   - none:                   No flags set.
+ *   - copyright:              Print copyright.
+ *   - header:                 Enable printing of headers.
+ *   - help:                   Print help.
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - return:                 The parameter is specified.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
  */
 #ifndef _di_control_main_flag_e_
   enum {
-    control_main_flag_none_e        = 0x0,
-    control_main_flag_copyright_e   = 0x1,
-    control_main_flag_help_e        = 0x2,
-    control_main_flag_pipe_e        = 0x4,
-    control_main_flag_print_first_e = 0x8,
-    control_main_flag_print_last_e  = 0x10,
-    control_main_flag_return_e      = 0x20,
-    control_main_flag_version_e     = 0x40,
+    control_main_flag_none_e                   = 0x0,
+    control_main_flag_copyright_e              = 0x1,
+    control_main_flag_help_e                   = 0x2,
+    control_main_flag_pipe_e                   = 0x4,
+    control_main_flag_print_first_e            = 0x8,
+    control_main_flag_print_last_e             = 0x10,
+    control_main_flag_return_e                 = 0x20,
+    control_main_flag_version_e                = 0x40,
+    control_main_flag_version_copyright_help_e = 0x43,
   }; // enum
 #endif // _di_control_main_flag_e_
 
@@ -126,7 +128,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(control_short_socket_s,   control_long_socket_s,   1, f_console_flag_normal_e), \
     }
 
-  #define control_parameter_total_d 17
+  #define control_parameter_total_d (f_console_parameter_state_type_total_d + 4)
 #endif // _di_control_parameter_d_
 
 /**
index ec9be63..7914da0 100644 (file)
@@ -23,7 +23,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (control_main_flag_help_e | control_main_flag_version_e | control_main_flag_copyright_e)) {
+    if (main->setting.flag & control_main_flag_version_copyright_help_e) {
       if (main->setting.flag & control_main_flag_help_e) {
         control_print_message_help(&main->program.message);
       }
index 291d488..18c9ddb 100644 (file)
@@ -45,7 +45,7 @@ extern "C" {
     fl_print_format("%[' with status '%]", print->to, print->set->error, print->set->error);
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, string_status, print->set->notable);
     fl_print_format("%[' (%]", print->to, print->set->error, print->set->error);
-    fl_print_format("%[%ui%]", print->to, print->set->notable, header.status, print->set->notable);
+    fl_print_format(f_string_format_ui_single_s.string, print->to, print->set->notable, header.status, print->set->notable);
 
     if (header.length) {
       fl_print_format("%[): %/Q%]%r", print->to, print->set->error, print->set->error, main->cache.large, main->cache.packet_contents.array[main->cache.packet_contents.used - 1].array[0], f_string_eol_s);
@@ -75,7 +75,7 @@ extern "C" {
     fl_print_format("%[' failed with status '%]", print->to, print->set->error, print->set->error);
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, string_status, print->set->notable);
     fl_print_format("%[' (%]", print->to, print->set->error, print->set->error);
-    fl_print_format("%[%ui%]", print->to, print->set->notable, header.status, print->set->notable);
+    fl_print_format(f_string_format_ui_single_s.string, print->to, print->set->notable, header.status, print->set->notable);
 
     if (header.length) {
       fl_print_format("%[): %/Q%]%r", print->to, print->set->error, print->set->error, main->cache.large, main->cache.packet_contents.array[main->cache.packet_contents.used - 1].array[0], f_string_eol_s);
index f6d401f..8f084ff 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
  *   The output structure to print to.
  *
  *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
  *
  * @return
  *   F_okay on success.
index da05cc4..fc34f4a 100644 (file)
@@ -31,9 +31,9 @@ extern "C" {
     f_file_stream_lock(print->to);
 
     fl_print_format("%[%QFailed while calling f_status_string_to() for status%] ", print->to, print->set->warning, print->set->warning, print->set->warning);
-    fl_print_format("%[%ui%]", print->to, print->set->notable, status_of, print->set->notable);
+    fl_print_format(f_string_format_ui_single_s.string, print->to, print->set->notable, status_of, print->set->notable);
     fl_print_format("%[, failing with status code%] ", print->to, print->set->warning, status_error, print->set->warning);
-    fl_print_format("%[%ui%]", print->to, print->set->notable, status_error, print->set->notable);
+    fl_print_format(f_string_format_ui_single_s.string, print->to, print->set->notable, status_error, print->set->notable);
     fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->warning, print->set->warning, f_string_eol_s);
 
     f_file_stream_unlock(print->to);
index b859f7a..c9a44e2 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_control_thread_signal_) && !defined(_di_thread_support_)
   void * control_thread_signal(void * const main) {
 
index f5a1d7f..0b40131 100644 (file)
@@ -160,7 +160,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(controller_short_validate_s,        controller_long_validate_s,        0, f_console_flag_normal_e), \
     }
 
-  #define controller_parameter_total_d 23
+  #define controller_parameter_total_d (f_console_parameter_state_type_total_d + 10)
 #endif // _di_controller_parameter_d_
 
 /**
index 23f0077..9797b1b 100644 (file)
@@ -530,7 +530,7 @@ extern "C" {
         fl_print_format("%r%[%QControl socket '%]", global->main->warning.to, f_string_eol_s, global->main->warning.context, global->main->warning.prefix, global->main->warning.context);
         fl_print_format(f_string_format_Q_single_s.string, global->main->output.to, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable);
         fl_print_format("%[' could not be created, code %]", global->main->output.to, global->main->warning.context, global->main->warning.context);
-        fl_print_format("%[%ui%]", global->main->output.to, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable);
+        fl_print_format(f_string_format_ui_single_s.string, global->main->output.to, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable);
         fl_print_format(f_string_format_sentence_end_s.string, global->main->output.to, global->main->warning.context, global->main->warning.context, f_string_eol_s);
 
         controller_unlock_print_flush(global->main->output.to, global->thread);
@@ -569,7 +569,7 @@ extern "C" {
         fl_print_format("%r%[%QControl socket '%]", global->main->warning.to, f_string_eol_s, global->main->warning.context, global->main->warning.prefix, global->main->warning.context);
         fl_print_format(f_string_format_Q_single_s.string, global->main->output.to, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable);
         fl_print_format("%[' could not be bound, code %]", global->main->output.to, global->main->warning.context, global->main->warning.context);
-        fl_print_format("%[%ui%]", global->main->output.to, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable);
+        fl_print_format(f_string_format_ui_single_s.string, global->main->output.to, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable);
         fl_print_format(f_string_format_sentence_end_s.string, global->main->output.to, global->main->warning.context, global->main->warning.context, f_string_eol_s);
 
         controller_unlock_print_flush(global->main->output.to, global->thread);
@@ -597,7 +597,7 @@ extern "C" {
           fl_print_format("%r%[%QControl socket '%]", global->main->warning.to, f_string_eol_s, global->main->warning.context, global->main->warning.prefix, global->main->warning.context);
           fl_print_format(f_string_format_Q_single_s.string, global->main->output.to, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable);
           fl_print_format("%[' failed to set file roles, code %]", global->main->output.to, global->main->warning.context, global->main->warning.context);
-          fl_print_format("%[%ui%]", global->main->output.to, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable);
+          fl_print_format(f_string_format_ui_single_s.string, global->main->output.to, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable);
           fl_print_format(f_string_format_sentence_end_s.string, global->main->output.to, global->main->warning.context, global->main->warning.context, f_string_eol_s);
 
           controller_unlock_print_flush(global->main->output.to, global->thread);
@@ -626,7 +626,7 @@ extern "C" {
           fl_print_format("%r%[%QControl socket '%]", global->main->warning.to, f_string_eol_s, global->main->warning.context, global->main->warning.prefix, global->main->warning.context);
           fl_print_format(f_string_format_Q_single_s.string, global->main->output.to, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable);
           fl_print_format("%[' failed to set file mode, code %]", global->main->output.to, global->main->warning.context, global->main->warning.context);
-          fl_print_format("%[%ui%]", global->main->output.to, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable);
+          fl_print_format(f_string_format_ui_single_s.string, global->main->output.to, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable);
           fl_print_format(f_string_format_sentence_end_s.string, global->main->output.to, global->main->warning.context, global->main->warning.context, f_string_eol_s);
 
           controller_unlock_print_flush(global->main->output.to, global->thread);
index d8013ad..6064462 100644 (file)
@@ -1887,7 +1887,7 @@ extern "C" {
           if (rerun_item->max) {
             fl_print_format(" for %[%ul%]", main->output.to, main->context.set.notable, rerun_item->count, main->context.set.notable);
             fl_print_format(" of %[%r%] ", main->output.to, main->context.set.notable, controller_max_s, main->context.set.notable);
-            fl_print_format("%[%ul%]", main->output.to, main->context.set.notable, rerun_item->max, main->context.set.notable);
+            fl_print_format(f_string_format_ul_single_s.string, main->output.to, main->context.set.notable, rerun_item->max, main->context.set.notable);
             fl_print_format(".%r", main->output.to, f_string_eol_s);
           }
           else {
index 97dc645..dc4869b 100644 (file)
@@ -77,54 +77,56 @@ extern "C" {
       macro_f_console_parameter_t_initialize_6(fake_other_operation_skeleton_s, 0, f_console_flag_simple_e), \
     }
 
-  #define fake_parameter_total_d 35
+  #define fake_parameter_total_d (f_console_parameter_state_type_total_d + 22)
 #endif // _di_fake_parameter_e_
 
 /**
  * Flags passed to the main function or program.
  *
  * fake_main_flag_*_e:
- *   - none:               No flags set.
- *   - copyright:          Print copyright.
- *   - enable_documents:   Enable documents, as in --enable-doc (not specifying means --disable-doc).
- *   - enable_shared:      Enable shared, as in --enable-shared (not specifying means --disable-shared).
- *   - enable_static:      Enable static, as in --enable-static (not specifying means --disable-static).
- *   - header:             Enable printing of headers.
- *   - help:               Print help.
- *   - operation:          Designate that an operation is explicitly passed.
- *   - operation_build:    The build operation is designated.
- *   - operation_clean:    The clean operation is designated.
- *   - operation_make:     The make operation is designated (or enabled as default).
- *   - operation_skeleton: The skeleton operation is designated.
- *   - pipe:               Use the input pipe.
- *   - print_first:        When set, print new line to message output on program begin after loading settings.
- *   - print_last:         When set, print new line to message output on program end.
- *   - separate:           Enable printing of separators.
- *   - strip_invalid:      Using strip invalid character mode.
- *   - verify:             Using verify mode.
- *   - version:            Print version.
+ *   - none:                   No flags set.
+ *   - copyright:              Print copyright.
+ *   - enable_documents:       Enable documents, as in --enable-doc (not specifying means --disable-doc).
+ *   - enable_shared:          Enable shared, as in --enable-shared (not specifying means --disable-shared).
+ *   - enable_static:          Enable static, as in --enable-static (not specifying means --disable-static).
+ *   - header:                 Enable printing of headers.
+ *   - help:                   Print help.
+ *   - operation:              Designate that an operation is explicitly passed.
+ *   - operation_build:        The build operation is designated.
+ *   - operation_clean:        The clean operation is designated.
+ *   - operation_make:         The make operation is designated (or enabled as default).
+ *   - operation_skeleton:     The skeleton operation is designated.
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - separate:               Enable printing of separators.
+ *   - strip_invalid:          Using strip invalid character mode.
+ *   - verify:                 Using verify mode.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
  */
 #ifndef _di_fake_main_flag_e_
   enum {
-    fake_main_flag_none_e               = 0x0,
-    fake_main_flag_copyright_e          = 0x1,
-    fake_main_flag_enable_documents_e   = 0x2,
-    fake_main_flag_enable_shared_e      = 0x4,
-    fake_main_flag_enable_static_e      = 0x8,
-    fake_main_flag_header_e             = 0x10,
-    fake_main_flag_help_e               = 0x20,
-    fake_main_flag_operation_e          = 0x40,
-    fake_main_flag_operation_build_e    = 0x80,
-    fake_main_flag_operation_clean_e    = 0x100,
-    fake_main_flag_operation_make_e     = 0x200,
-    fake_main_flag_operation_skeleton_e = 0x400,
-    fake_main_flag_pipe_e               = 0x800,
-    fake_main_flag_print_first_e        = 0x1000,
-    fake_main_flag_print_last_e         = 0x2000,
-    fake_main_flag_separate_e           = 0x4000,
-    fake_main_flag_strip_invalid_e      = 0x8000,
-    fake_main_flag_verify_e             = 0x10000,
-    fake_main_flag_version_e            = 0x20000,
+    fake_main_flag_none_e                   = 0x0,
+    fake_main_flag_copyright_e              = 0x1,
+    fake_main_flag_enable_documents_e       = 0x2,
+    fake_main_flag_enable_shared_e          = 0x4,
+    fake_main_flag_enable_static_e          = 0x8,
+    fake_main_flag_header_e                 = 0x10,
+    fake_main_flag_help_e                   = 0x20,
+    fake_main_flag_operation_e              = 0x40,
+    fake_main_flag_operation_build_e        = 0x80,
+    fake_main_flag_operation_clean_e        = 0x100,
+    fake_main_flag_operation_make_e         = 0x200,
+    fake_main_flag_operation_skeleton_e     = 0x400,
+    fake_main_flag_pipe_e                   = 0x800,
+    fake_main_flag_print_first_e            = 0x1000,
+    fake_main_flag_print_last_e             = 0x2000,
+    fake_main_flag_separate_e               = 0x4000,
+    fake_main_flag_strip_invalid_e          = 0x8000,
+    fake_main_flag_verify_e                 = 0x10000,
+    fake_main_flag_version_e                = 0x20000,
+    fake_main_flag_version_copyright_help_e = 0x20021,
   }; // enum
 #endif // _di_fake_main_flag_e_
 
index 0db1729..aae7120 100644 (file)
@@ -23,7 +23,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (fake_main_flag_help_e | fake_main_flag_version_e | fake_main_flag_copyright_e)) {
+    if (main->setting.flag & fake_main_flag_version_copyright_help_e) {
       if (main->setting.flag & fake_main_flag_help_e) {
         fake_print_message_help(&main->program.message);
       }
index d5791b8..2b4040a 100644 (file)
@@ -163,7 +163,7 @@ extern "C" {
       f_file_stream_lock(print->to);
 
       fl_print_format("%[UNKNOWN %Q(%]", print->to, print->context, print->prefix, print->context);
-      fl_print_format("%[%ui%]", print->to, print->notable, F_status_set_fine(main->setting.state.status), print->notable);
+      fl_print_format(f_string_format_ui_single_s.string, print->to, print->notable, F_status_set_fine(main->setting.state.status), print->notable);
       fl_print_format("%[) occurred ", print->to, print->context);
 
       fake_print_error_build_operation_file_partial(print, operation, source, destination, how);
@@ -599,9 +599,9 @@ extern "C" {
     fl_print_format("%[' from section '%]", print->to, print->context, buffer, print->context);
     fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->notable, buffer, section_name, print->notable);
     fl_print_format("%[' on line%] ", print->to, print->context, print->context);
-    fl_print_format("%[%ul%]", print->to, print->notable, line, print->notable);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->notable, line, print->notable);
     fl_print_format("%[' cannot be processed because the max stack depth of%] ", print->to, print->context, print->context);
-    fl_print_format("%[%ul%]", print->to, print->notable, stack_max, print->notable);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->notable, stack_max, print->notable);
     fl_print_format(" %[has been reached.%]%r", print->to, print->context, print->context, f_string_eol_s);
 
     f_file_stream_unlock(print->to);
@@ -632,7 +632,7 @@ extern "C" {
     fl_print_format("%[' from section '%]", print->to, print->context, buffer, print->context);
     fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->notable, buffer, section_name, print->notable);
     fl_print_format("%[' on line%] ", print->to, print->context, print->context);
-    fl_print_format("%[%ul%]", print->to, print->notable, line, print->notable);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->notable, line, print->notable);
     fl_print_format(" %[is not a known operation name.%]%r", print->to, print->context, print->context, f_string_eol_s);
 
     f_file_stream_unlock(print->to);
index 05e9d16..b8ead8c 100644 (file)
@@ -5,7 +5,7 @@
  * API Version: 0.7
  * Licenses: lgpl-2.1-or-later
  *
- * Provides error print functionality.
+ * Provides print error functionality.
  *
  * This is auto-included and should not need to be explicitly included.
  */
index 60b1d31..11131a4 100644 (file)
@@ -100,7 +100,9 @@ extern "C" {
     fll_program_print_help_option(print, fake_short_under_s, fake_long_under_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "    Specify a custom path the data build files are under.");
     fll_program_print_help_option(print, fake_short_work_s, fake_long_work_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "     Use includes/libraries/programs from this directory instead of system.");
 
-    fl_print_format("%r %[Special Options:%]%r", print->to, f_string_eol_s, print->set->important, print->set->important, f_string_eol_s);
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    fll_program_print_help_special_options(print);
 
     fll_program_print_help_option_long(print, fake_long_documents_disabled_s, f_console_symbol_long_normal_s, "   Forcibly do not build documents files.");
     fll_program_print_help_option_long(print, fake_long_documents_enabled_s, f_console_symbol_long_normal_s, "    Forcibly do build documents files.");
@@ -109,7 +111,9 @@ extern "C" {
     fll_program_print_help_option_long(print, fake_long_static_disabled_s, f_console_symbol_long_normal_s, "Forcibly do not build static files.");
     fll_program_print_help_option_long(print, fake_long_static_enabled_s, f_console_symbol_long_normal_s, " Forcibly do build static files.");
 
-    fl_print_format("%r %[Operations:%] %r", print->to, f_string_eol_s, print->set->important, print->set->important, f_string_eol_s);
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    fll_program_print_help_operations(print);
 
     fll_program_print_help_option_other(print, fake_other_operation_build_s, "   Build or compile the code based on build settings file.");
     fll_program_print_help_option_other(print, fake_other_operation_clean_s, "   Delete all build files.");
index a123ce5..8e7b884 100644 (file)
@@ -5,7 +5,7 @@
  * API Version: 0.7
  * Licenses: lgpl-2.1-or-later
  *
- * Provides the verbose print functionality.
+ * Provides the print verbose functionality.
  *
  * This is auto-included and should not need to be explicitly included.
  */
index a84cdf9..1c18b92 100644 (file)
@@ -5,7 +5,7 @@
  * API Version: 0.7
  * Licenses: lgpl-2.1-or-later
  *
- * Provides the warning print functionality.
+ * Provides the print warning functionality.
  *
  * This is auto-included and should not need to be explicitly included.
  */
index 110e0f7..5cbbefe 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_)
   void * fake_thread_signal(void * const main) {
 
diff --git a/level_3/firewall/c/firewall.c b/level_3/firewall/c/firewall.c
deleted file mode 100644 (file)
index a034d7c..0000000
+++ /dev/null
@@ -1,702 +0,0 @@
-/**
- * FLL - Level 3
- * Project: Firewall
- * API Version: 0.5
- * Licenses: lgpl-2.1-or-later
- */
-#include "firewall.h"
-#include "private-common.h"
-#include "private-firewall.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _di_firewall_main_
-  f_status_t firewall_main(fll_program_data_t * const main, firewall_setting_t * const setting) {
-
-    f_status_t status = F_okay;
-
-    setting->state.step_small = firewall_allocation_console_d;
-
-    status = f_console_parameter_process(arguments, &main->parameters, &setting->state, 0);
-
-    setting->state.step_small = firewall_allocation_small_d;
-
-    if (F_status_is_error(status)) return;
-
-    status = fll_program_parameter_process_context_standard(F_true, &main->program);
-
-    if (F_status_is_error(status)) {
-      fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process_context_standard", fll_error_file_flag_fallback_e);
-
-      if (main->error.verbosity > f_console_verbosity_quiet_e) {
-        fll_print_dynamic_raw(f_string_eol_s, main->error);
-      }
-
-      return;
-    }
-
-    status = fll_program_parameter_process_verbosity_standard(F_true, &main->program);
-
-    if (F_status_is_error(status)) {
-      fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process_verbosity_standard", fll_error_file_flag_fallback_e);
-
-      if (main->error.verbosity > f_console_verbosity_quiet_e) {
-        fll_print_dynamic_raw(f_string_eol_s, main->error);
-      }
-
-      return;
-    }
-
-    if (main->parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) {
-      firewall_print_help(setting, main->message);
-
-      return F_okay;
-    }
-
-    if (main->parameters.array[f_console_standard_parameter_version_e].result & f_console_result_found_e) {
-      fll_program_print_version(&main->message, firewall_program_version_s);
-
-      return F_okay;
-    }
-
-    if (main->parameters.array[f_console_standard_parameter_copyright_e].result & f_console_result_found_e) {
-      fll_program_print_copyright(&main->message);
-
-      return F_okay;
-    }
-
-    status = F_okay;
-
-    firewall_data_t data = firewall_data_t_initialize;
-    data.main = main;
-    data.argv = main->parameters.arguments.array;
-
-    // now determine which command was placed first
-    bool found_command = F_false;
-    unsigned int command = 0;
-
-    if (main->parameters.array[firewall_parameter_command_start_e].result & f_console_result_found_e) {
-      command = firewall_parameter_command_start_e;
-      found_command = F_true;
-    }
-
-    if (main->parameters.array[firewall_parameter_command_stop_e].result & f_console_result_found_e) {
-      if (found_command) {
-        if (main->parameters.array[command].values.array[0] > main->parameters.array[firewall_parameter_command_stop_e].values.array[0]) {
-          command = firewall_parameter_command_stop_e;
-        }
-      }
-      else {
-        command = firewall_parameter_command_stop_e;
-        found_command = F_true;
-      }
-    }
-
-    if (main->parameters.array[firewall_parameter_command_restart_e].result & f_console_result_found_e) {
-      if (found_command) {
-        if (main->parameters.array[command].values.array[0] > main->parameters.array[firewall_parameter_command_restart_e].values.array[0]) {
-          command = firewall_parameter_command_restart_e;
-        }
-      }
-      else {
-        command = firewall_parameter_command_restart_e;
-        found_command = F_true;
-      }
-    }
-
-    if (main->parameters.array[firewall_parameter_command_lock_e].result & f_console_result_found_e) {
-      if (found_command) {
-        if (main->parameters.array[command].values.array[0] > main->parameters.array[firewall_parameter_command_lock_e].values.array[0]) {
-          command = firewall_parameter_command_lock_e;
-        }
-      }
-      else {
-        command = firewall_parameter_command_lock_e;
-        found_command = F_true;
-      }
-    }
-
-    if (main->parameters.array[firewall_parameter_command_show_e].result & f_console_result_found_e) {
-      if (found_command) {
-        if (main->parameters.array[command].values.array[0] > main->parameters.array[firewall_parameter_command_show_e].values.array[0]) {
-          command = firewall_parameter_command_show_e;
-        }
-      }
-      else {
-        command = firewall_parameter_command_show_e;
-        found_command = F_true;
-      }
-    }
-
-    if (found_command) {
-      firewall_local_data_t local = firewall_local_data_t_initialize;
-      firewall_reserved_chains_t reserved = firewall_reserved_chains_t_initialize;
-      f_range_t input = f_range_t_initialize;
-
-      if (command == firewall_parameter_command_show_e) {
-
-        // Warning: these are hardcoded print commands.
-        bool show_nat = F_true;
-        bool show_mangle = F_true;
-        bool show_ports = F_true;
-
-        int return_code = 0;
-
-        if (main->parameters.remaining.used) {
-          show_nat = F_false;
-          show_mangle = F_false;
-          show_ports = F_false;
-
-          f_number_unsigned_t index = 0;
-
-          for (f_number_unsigned_t i = 0; i < main->parameters.remaining.used; ++i) {
-
-            index = main->parameters.remaining.array[i];
-
-            if (f_compare_dynamic(firewall_show_nat_s, data.argv[index]) == F_equal_to) {
-              show_nat = F_true;
-            }
-            else {
-              if (f_compare_dynamic(firewall_show_mangle_s, data.argv[index]) == F_equal_to) {
-                show_mangle = F_true;
-              }
-              else {
-                if (f_compare_dynamic(firewall_show_ports_s, data.argv[index]) == F_equal_to) {
-                  show_ports = F_true;
-                }
-                else {
-                  f_file_stream_lock(main->warning.to);
-
-                  fl_print_format("%r%[%Q'%]", main->warning.to, f_string_eol_s, main->warning.context, main->warning.prefix, main->warning.context);
-                  fl_print_format(f_string_format_Q_single_s.string, main->warning.to, main->warning.notable, data.argv[index], main->warning.notable);
-                  fl_print_format("%[' is not a valid show option.%]%r", main->warning.to, main->warning.context, main->warning.context, f_string_eol_s);
-
-                  f_file_stream_unlock(main->warning.to);
-                  f_file_stream_flush(main->warning.to);
-                }
-              }
-            }
-          } // for
-        }
-
-        f_string_statics_t parameters = f_string_statics_t_initialize;
-        parameters.used = 6;
-
-        f_string_static_t parameters_array[parameters.used];
-        parameters.array = parameters_array;
-
-        parameters_array[0] = firewall_show_parameter_exact_s;
-        parameters_array[1] = firewall_show_parameter_verbose_s;
-        parameters_array[2] = firewall_show_parameter_table_s;
-        parameters_array[3] = firewall_show_nat_s;
-        parameters_array[4] = firewall_show_parameter_numeric_s;
-        parameters_array[5] = firewall_show_parameter_list_s;
-
-        if (show_nat) {
-          fll_print_format("%[===========================%] %[NAT%] %[============================%]%r", main->output.to, main->context.set.standout, main->context.set.standout, main->context.set.title, main->context.set.title, main->context.set.standout, main->context.set.standout, f_string_eol_s);
-          f_file_stream_flush(main->output.to);
-
-          status = fll_execute_program(firewall_tool_iptables_s, parameters, 0, 0, (void *) &return_code);
-
-          if (status == F_child) {
-            main->child = return_code;
-
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
-          }
-
-          fll_print_dynamic_raw(f_string_eol_s, main->output.to);
-          f_file_stream_flush(main->output.to);
-        }
-
-        if (F_status_is_error_not(status) && show_mangle) {
-          fll_print_format("%[==========================%] %[MANGLE%] %[==========================%]%r", main->output.to, main->context.set.standout, main->context.set.standout, main->context.set.title, main->context.set.title, main->context.set.standout, main->context.set.standout, f_string_eol_s);
-          f_file_stream_flush(main->output.to);
-
-          parameters_array[3] = firewall_show_mangle_s;
-
-          status = fll_execute_program(firewall_tool_iptables_s, parameters, 0, 0, (void *) &return_code);
-
-          if (status == F_child) {
-            main->child = return_code;
-
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
-          }
-
-          fll_print_dynamic_raw(f_string_eol_s, main->output.to);
-          f_file_stream_flush(main->output.to);
-        }
-
-        if (F_status_is_error_not(status) && show_ports) {
-          fll_print_format("%[==========================%] %[FILTER%] %[==========================%]%r", main->output.to, main->context.set.standout, main->context.set.standout, main->context.set.title, main->context.set.title, main->context.set.standout, main->context.set.standout, f_string_eol_s);
-          f_file_stream_flush(main->output.to);
-
-          parameters_array[0] = firewall_show_parameter_exact_s;
-          parameters_array[1] = firewall_show_parameter_verbose_s;
-          parameters_array[2] = firewall_show_parameter_numeric_s;
-          parameters_array[3] = firewall_show_parameter_list_s;
-          parameters.used = 4;
-
-          status = fll_execute_program(firewall_tool_iptables_s, parameters, 0, 0, (void *) &return_code);
-
-          if (status == F_child) {
-            main->child = return_code;
-
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
-          }
-
-          fll_print_dynamic_raw(f_string_eol_s, main->output.to);
-          f_file_stream_flush(main->output.to);
-        }
-
-        if (F_status_is_error(status)) {
-          status = F_status_set_fine(status);
-
-          if (status == F_memory_not) {
-            firewall_print_error_on_allocation_failure(main->error);
-          }
-          else {
-            firewall_print_error_on_operation(main->error, firewall_tool_iptables_s, parameters);
-          }
-
-          status = F_status_set_error(status);
-        }
-
-        firewall_delete_local_data(&local);
-        firewall_data_delete(&data);
-
-        return status;
-      }
-
-      // Load all network devices.
-      status = f_directory_list(firewall_network_devices_s, 0, alphasort, &data.devices);
-
-      if (F_status_is_error(status)) {
-        status = F_status_set_fine(status);
-
-        if (main->error.verbosity > f_console_verbosity_quiet_e) {
-          if (status == F_memory_not) {
-            firewall_print_error_on_allocation_failure(main->error);
-          }
-          else if (status == F_data_not) {
-            fll_print_format("%r%[%QCould not find any network devices.%]%r", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context, f_string_eol_s);
-          }
-          else if (status == F_failure) {
-            fll_print_format("%r%[%QFailed to read the device directory '%r'.%]%r", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, firewall_network_devices_s, main->error.context, f_string_eol_s);
-          }
-        }
-
-        firewall_delete_local_data(&local);
-        firewall_data_delete(&data);
-
-        return F_status_set_error(status);
-      }
-
-      // Remove "lo" (loopback) from the device listing.
-      {
-        f_number_unsigned_t i = 0;
-
-        for (; i < data.devices.used; ++i) {
-
-          if (f_compare_dynamic(firewall_device_loop_s, data.devices.array[i]) == F_equal_to) {
-            f_string_static_t swap_string = data.devices.array[i];
-
-            --data.devices.used;
-
-            for (; i < data.devices.used; ++i) {
-              data.devices.array[i] = data.devices.array[i + 1];
-            } // for
-
-            data.devices.array[data.devices.used] = swap_string;
-          }
-        } // for
-      }
-
-      if (command == firewall_parameter_command_stop_e || command == firewall_parameter_command_restart_e || command == firewall_parameter_command_lock_e) {
-        f_string_static_t path_file_other = f_string_static_t_initialize;
-        path_file_other.used = firewall_network_path_s.used + firewall_file_other_s.used;
-
-        f_char_t path_file_other_string[path_file_other.used + 1];
-        path_file_other.string = path_file_other_string;
-        path_file_other_string[path_file_other.used] = 0;
-
-        memcpy(path_file_other_string, firewall_network_path_s.string, sizeof(f_char_t) * firewall_network_path_s.used);
-        memcpy(path_file_other_string + firewall_network_path_s.used, firewall_file_other_s.string, sizeof(f_char_t) * firewall_file_other_s.used);
-
-        status = firewall_buffer_rules(&data, path_file_other, F_false, &local);
-
-        if (F_status_is_error(status) || status == F_child) {
-          firewall_delete_local_data(&local);
-          firewall_data_delete(&data);
-
-          return status;
-        }
-
-        for (f_number_unsigned_t i = 0; i < local.chain_objects.used; ++i) {
-
-          if (!reserved.has_stop && f_compare_dynamic_partial_string(firewall_group_stop_s.string, local.buffer, firewall_group_stop_s.used, local.chain_objects.array[i]) == F_equal_to) {
-            reserved.stop_at = i;
-            reserved.has_stop = F_true;
-          }
-          else if (!reserved.has_lock && f_compare_dynamic_partial_string(firewall_group_lock_s.string, local.buffer, firewall_group_lock_s.used, local.chain_objects.array[i]) == F_equal_to) {
-            reserved.lock_at = i;
-            reserved.has_lock = F_true;
-          }
-        } // for
-
-        if (command == firewall_parameter_command_lock_e) {
-          if (reserved.has_lock) {
-            status = firewall_delete_chains(&data);
-
-            if (F_status_is_error_not(status) && status != F_child) {
-              status = firewall_default_lock(&data);
-            }
-
-            if (F_status_is_error(status) || status == F_child) {
-              firewall_delete_local_data(&local);
-              firewall_data_delete(&data);
-
-              return status;
-            }
-
-            local.is_main = F_false;
-            local.is_stop = F_false;
-            local.is_lock = F_true;
-            local.chain = reserved.lock_at;
-
-            input.start = local.chain_contents.array[reserved.lock_at].array[0].start;
-            input.stop = local.chain_contents.array[reserved.lock_at].array[0].stop;
-
-            status = firewall_process_rules(&data, &input, &local);
-
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
-          }
-
-          if (main->error.verbosity > f_console_verbosity_quiet_e) {
-            fll_print_format("%r%[%QFailed to perform lock request because the lock instructions are missing from: %r.%]%r", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, path_file_other, main->error.context, f_string_eol_s);
-          }
-
-          firewall_delete_local_data(&local);
-
-          return F_status_set_error(F_data);
-        }
-
-        if (command == firewall_parameter_command_stop_e || command == firewall_parameter_command_restart_e) {
-          if (reserved.has_stop) {
-            status = firewall_delete_chains(&data);
-
-            if (F_status_is_error_not(status) && status != F_child) {
-              status = firewall_default_lock(&data);
-            }
-
-            if (F_status_is_error(status) || status == F_child) {
-              firewall_delete_local_data(&local);
-              firewall_data_delete(&data);
-
-              return status;
-            }
-
-            local.is_global = F_true;
-            local.is_main = F_false;
-            local.is_stop = F_true;
-            local.is_lock = F_false;
-            local.chain = reserved.stop_at;
-
-            input.start = local.chain_contents.array[reserved.stop_at].array[0].start;
-            input.stop = local.chain_contents.array[reserved.stop_at].array[0].stop;
-
-            status = firewall_process_rules(&data, &input, &local);
-
-            if (F_status_is_error(status) || command == firewall_parameter_command_stop_e || status == F_child) {
-              firewall_delete_local_data(&local);
-
-              return status;
-            }
-          }
-          else {
-            if (main->error.verbosity > f_console_verbosity_quiet_e) {
-              fll_print_format("%r%[%QFailed to perform stop request because the lock instructions are missing from: %r.%]%r", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, path_file_other, main->error.context, f_string_eol_s);
-            }
-
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return F_status_set_error(F_data);
-          }
-        }
-
-        firewall_delete_local_data(&local);
-      }
-
-      if (command == firewall_parameter_command_start_e || command == firewall_parameter_command_restart_e) {
-        f_string_static_t path_file_first = f_string_static_t_initialize;
-        path_file_first.used = firewall_network_path_s.used + firewall_file_first_s.used;
-
-        f_char_t path_file_first_string[path_file_first.used + 1];
-        path_file_first.string = path_file_first_string;
-        path_file_first_string[path_file_first.used] = 0;
-
-        memcpy(path_file_first_string, firewall_network_path_s.string, sizeof(f_char_t) * firewall_network_path_s.used);
-        memcpy(path_file_first_string + firewall_network_path_s.used, firewall_file_first_s.string, sizeof(f_char_t) * firewall_file_first_s.used);
-
-        status = firewall_buffer_rules(&data, path_file_first, F_false, &local);
-
-        if (F_status_is_error(status) || status == F_child) {
-          firewall_delete_local_data(&local);
-          firewall_data_delete(&data);
-
-          return status;
-        }
-
-        if (command == firewall_parameter_command_start_e) {
-          status = firewall_delete_chains(&data);
-
-          if (F_status_is_error_not(status) && status != F_child) {
-            status = firewall_default_lock(&data);
-          }
-
-          if (F_status_is_error(status) || status == F_child) {
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
-          }
-        }
-
-        status = firewall_create_custom_chains(&data, &reserved, &local);
-
-        if (F_status_is_error(status) || status == F_child) {
-          firewall_delete_local_data(&local);
-          firewall_data_delete(&data);
-
-          return status;
-        }
-
-        f_number_unsigned_t i = 0;
-
-        local.is_global = F_true;
-        local.is_stop = F_false;
-        local.is_lock = F_false;
-
-        while (i < local.chain_contents.used) {
-
-          input.start = local.chain_contents.array[i].array[0].start;
-          input.stop = local.chain_contents.array[i].array[0].stop;
-
-          local.is_main = reserved.has_main && i == reserved.main_at ? F_true : F_false;
-          local.chain = i;
-
-          status = firewall_process_rules(&data, &input, &local);
-
-          if (F_status_is_error(status) || command == firewall_parameter_command_stop_e || status == F_child) {
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
-          }
-
-          ++i;
-        } // while
-
-        firewall_delete_local_data(&local);
-
-        {
-          f_string_dynamic_t path_file = f_string_dynamic_t_initialize;
-          f_number_unsigned_t j = 0;
-
-          for (i = 0; i < data.devices.used; ++i) {
-
-            path_file.used = 0;
-            local.device = i;
-
-            status = f_memory_array_increase_by(firewall_network_path_s.used + data.devices.array[i].used + firewall_file_suffix_s.used + 1, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-
-            if (F_status_is_error_not(status)) {
-              status = f_string_dynamic_append(firewall_network_path_s, &path_file);
-            }
-
-            if (F_status_is_error_not(status)) {
-              status = f_string_dynamic_append(data.devices.array[i], &path_file);
-            }
-
-            if (F_status_is_error_not(status)) {
-              status = f_string_dynamic_append(firewall_file_suffix_s, &path_file);
-            }
-
-            if (F_status_is_error(status)) {
-              firewall_print_error_on_allocation_failure(main->error);
-
-              firewall_delete_local_data(&local);
-              firewall_data_delete(&data);
-
-              return status;
-            }
-
-            status = firewall_buffer_rules(&data, path_file, F_true, &local);
-
-            if (status == F_child) {
-              firewall_delete_local_data(&local);
-              firewall_data_delete(&data);
-
-              f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-
-              return status;
-            }
-
-            if (F_status_is_error(status)) {
-              status = F_status_set_fine(status);
-
-              firewall_delete_local_data(&local);
-
-              if (status == F_file_found_not || status == F_file_open || status == F_file_descriptor || status == F_fss_found_object_content_not) {
-                status = F_status_set_error(status);
-
-                continue;
-              }
-
-              f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-              firewall_data_delete(&data);
-
-              return F_status_set_error(status);
-            }
-
-            status = firewall_create_custom_chains(&data, &reserved, &local);
-
-            if (F_status_is_error(status) || status == F_child) {
-              firewall_delete_local_data(&local);
-              firewall_data_delete(&data);
-
-              return status;
-            }
-
-            local.is_global = F_false;
-            local.is_stop = F_false;
-            local.is_lock = F_false;
-
-            for (j = 0; j < local.chain_contents.used; ++j) {
-
-              input.start = local.chain_contents.array[j].array[0].start;
-              input.stop = local.chain_contents.array[j].array[0].stop;
-
-              local.is_main = reserved.has_main && j == reserved.main_at ? F_true : F_false;
-              local.chain = j;
-
-              status = firewall_process_rules(&data, &input, &local);
-
-              if (F_status_is_error(status) || command == firewall_parameter_command_stop_e || status == F_child) {
-                f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-
-                firewall_delete_local_data(&local);
-                firewall_data_delete(&data);
-
-                return status;
-              }
-            } // for
-
-            firewall_delete_local_data(&local);
-          } // for
-
-          path_file.used = 0;
-
-          status = f_string_dynamic_append(firewall_network_path_s, &path_file);
-
-          if (F_status_is_error_not(status)) {
-            status = f_string_dynamic_append(firewall_file_last_s, &path_file);
-          }
-
-          if (F_status_is_error_not(status)) {
-            status = firewall_buffer_rules(&data, path_file, F_false, &local);
-          }
-
-          if (F_status_is_error(status) || status == F_child) {
-            f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
-          }
-
-          status = firewall_create_custom_chains(&data, &reserved, &local);
-
-          if (F_status_is_error(status) || status == F_child) {
-            f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
-          }
-
-          i = 0;
-
-          local.is_global = F_true;
-          local.is_stop = F_false;
-          local.is_lock = F_false;
-
-          while (i < local.chain_contents.used) {
-
-            input.start = local.chain_contents.array[i].array[0].start;
-            input.stop = local.chain_contents.array[i].array[0].stop;
-
-            local.is_main = reserved.has_main && i == reserved.main_at ? F_true : F_false;
-            local.chain = i;
-
-            status = firewall_process_rules(&data, &input, &local);
-
-            if (F_status_is_error(status) || command == firewall_parameter_command_stop_e || status == F_child) {
-              f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-
-              firewall_delete_local_data(&local);
-              firewall_data_delete(&data);
-
-              return status;
-            }
-
-            ++i;
-          } // while
-
-          f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-        }
-      }
-
-      firewall_delete_local_data(&local);
-    }
-    else {
-      if (main->error.verbosity > f_console_verbosity_quiet_e) {
-        fll_print_format("%r%[%QNo command given.%]%r", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context, f_string_eol_s);
-      }
-
-      status = F_status_set_error(F_parameter);
-    }
-
-    if (main->error.verbosity > f_console_verbosity_quiet_e) {
-      if (F_status_set_fine(status) == F_interrupt) {
-        f_file_stream_flush(main->output.to);
-
-        fll_print_dynamic_raw(f_string_eol_s, main->output.to);
-      }
-    }
-
-    firewall_data_delete(&data);
-
-    return status;
-  }
-#endif // _di_firewall_main_
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/level_3/firewall/c/firewall.h b/level_3/firewall/c/firewall.h
deleted file mode 100644 (file)
index 4522a86..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * FLL - Level 3
- *
- * Project: Firewall
- * API Version: 0.7
- * Licenses: lgpl-2.1-or-later
- *
- * This is the Kevux Operating System Firewall program.
- * This program utilizes the Featureless Linux Library.
- * This program processes firewall commands and passes them to iptables from netfiler.org.
- */
-#ifndef _firewall_h
-#define _firewall_h
-
-// Libc includes.
-#include <dirent.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-// FLL-0 includes.
-#include <fll/level_0/type.h>
-#include <fll/level_0/status.h>
-#include <fll/level_0/memory.h>
-#include <fll/level_0/type_array.h>
-#include <fll/level_0/string.h>
-#include <fll/level_0/utf.h>
-#include <fll/level_0/color.h>
-#include <fll/level_0/compare.h>
-#include <fll/level_0/console.h>
-#include <fll/level_0/directory.h>
-#include <fll/level_0/execute.h>
-#include <fll/level_0/file.h>
-#include <fll/level_0/pipe.h>
-#include <fll/level_0/print.h>
-#include <fll/level_0/rip.h>
-#include <fll/level_0/signal.h>
-
-// FLL-1 includes.
-#include <fll/level_1/print.h>
-
-// FLL-2 includes.
-#include <fll/level_2/error.h>
-#include <fll/level_2/execute.h>
-#include <fll/level_2/fss/basic.h>
-#include <fll/level_2/fss/basic_list.h>
-#include <fll/level_2/fss/extended.h>
-#include <fll/level_2/print.h>
-#include <fll/level_2/program.h>
-
-// Firewall includes.
-#include <program/firewall/common.h>
-#include <program/firewall/print.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Execute main program.
- *
- * If main.signal is non-zero, then this blocks and handles the following signals:
- *   - F_signal_abort
- *   - F_signal_broken_pipe
- *   - F_signal_hangup
- *   - F_signal_interrupt
- *   - F_signal_quit
- *   - F_signal_termination
- *
- * @param main
- *   The main program data.
- * @param arguments
- *   The parameters passed to the process.
- *
- * @return
- *   F_okay on success.
- *
- *   F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal.
- *
- *   Status codes (with error bit) are returned on any problem.
- */
-#ifndef _di_firewall_main_
-  extern f_status_t firewall_main(fll_program_data_t * const main, firewall_setting_t * const setting);
-#endif // _di_firewall_main_
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // _firewall_h
diff --git a/level_3/firewall/c/main/common.c b/level_3/firewall/c/main/common.c
new file mode 100644 (file)
index 0000000..4d28f17
--- /dev/null
@@ -0,0 +1,186 @@
+#include "firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_setting_load_
+  void firewall_setting_load(const f_console_arguments_t arguments, firewall_main_t * const main) {
+
+    if (!main) return;
+
+    main->setting.state.step_small = firewall_allocation_console_d;
+
+    f_console_parameter_process(arguments, &main->program.parameters, &main->setting.state, 0);
+
+    main->setting.state.step_small = firewall_allocation_small_d;
+
+    // Identify and process first/last parameters.
+    if (main->program.parameters.array[f_console_standard_parameter_line_first_no_e].result & f_console_result_found_e) {
+      main->setting.flag &= ~firewall_main_flag_print_first_e;
+    }
+    else {
+      main->setting.flag |= firewall_main_flag_print_first_e;
+    }
+
+    if (main->program.parameters.array[f_console_standard_parameter_line_last_no_e].result & f_console_result_found_e) {
+      main->setting.flag &= ~firewall_main_flag_print_last_e;
+    }
+    else {
+      main->setting.flag |= firewall_main_flag_print_last_e;
+    }
+
+    if (F_status_is_error(main->setting.state.status)) {
+      if ((main->setting.flag & firewall_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+        fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+      }
+
+      firewall_print_error(&main->program.error, macro_firewall_f(f_console_parameter_process));
+
+      return;
+    }
+
+    main->setting.state.status = fll_program_parameter_process_context_standard(F_true, &main->program);
+
+    if (F_status_is_error(main->setting.state.status)) {
+      if ((main->setting.flag & firewall_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+        fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+      }
+
+      firewall_print_error(&main->program.error, macro_firewall_f(fll_program_parameter_process_context_standard));
+
+      return;
+    }
+
+    main->setting.state.status = fll_program_parameter_process_verbosity_standard(F_true, &main->program);
+
+    if (F_status_is_error(main->setting.state.status)) {
+      if ((main->setting.flag & firewall_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+        fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+      }
+
+      firewall_print_error(&main->program.error, macro_firewall_f(fll_program_parameter_process_verbosity_standard));
+
+      return;
+    }
+
+    if (main->program.parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) {
+      main->setting.flag |= firewall_main_flag_help_e;
+
+      return;
+    }
+
+    if (main->program.parameters.array[f_console_standard_parameter_version_e].result & f_console_result_found_e) {
+      main->setting.flag |= firewall_main_flag_version_e;
+
+      return;
+    }
+
+    if (main->program.parameters.array[f_console_standard_parameter_copyright_e].result & f_console_result_found_e) {
+      main->setting.flag |= firewall_main_flag_copyright_e;
+
+      return;
+    }
+
+    f_number_unsigned_t at = 0;
+
+    if (main->program.parameters.array[firewall_parameter_operation_start_e].result & f_console_result_found_e) {
+      main->setting.flag &= ~firewall_main_flag_operation_lock_e;
+      main->setting.flag &= ~firewall_main_flag_operation_restart_e;
+      main->setting.flag &= ~firewall_main_flag_operation_show_e;
+      main->setting.flag &= ~firewall_main_flag_operation_stop_e;
+
+      main->setting.flag |= firewall_main_flag_operation_start_e;
+
+      at = main->program.parameters.array[firewall_parameter_operation_start_e].values.array[0];
+    }
+
+    if (main->program.parameters.array[firewall_parameter_operation_stop_e].result & f_console_result_found_e) {
+      if (!(main->setting.flag & firewall_main_flag_operation_e) || (main->program.parameters.array[at].values.array[0] > main->program.parameters.array[firewall_parameter_operation_stop_e].values.array[0])) {
+        main->setting.flag &= ~firewall_main_flag_operation_lock_e;
+        main->setting.flag &= ~firewall_main_flag_operation_restart_e;
+        main->setting.flag &= ~firewall_main_flag_operation_show_e;
+        main->setting.flag &= ~firewall_main_flag_operation_start_e;
+
+        main->setting.flag |= firewall_main_flag_operation_stop_e;
+
+        at = main->program.parameters.array[firewall_parameter_operation_stop_e].values.array[0];
+      }
+    }
+
+    if (main->program.parameters.array[firewall_parameter_operation_restart_e].result & f_console_result_found_e) {
+      if (!(main->setting.flag & firewall_main_flag_operation_e) || (main->program.parameters.array[at].values.array[0] > main->program.parameters.array[firewall_parameter_operation_restart_e].values.array[0])) {
+        main->setting.flag &= ~firewall_main_flag_operation_lock_e;
+        main->setting.flag &= ~firewall_main_flag_operation_show_e;
+        main->setting.flag &= ~firewall_main_flag_operation_start_e;
+        main->setting.flag &= ~firewall_main_flag_operation_stop_e;
+
+        main->setting.flag |= firewall_main_flag_operation_restart_e;
+
+        at = main->program.parameters.array[firewall_parameter_operation_restart_e].values.array[0];
+      }
+    }
+
+    if (main->program.parameters.array[firewall_parameter_operation_lock_e].result & f_console_result_found_e) {
+      if (!(main->setting.flag & firewall_main_flag_operation_e) || (main->program.parameters.array[at].values.array[0] > main->program.parameters.array[firewall_parameter_operation_lock_e].values.array[0])) {
+        main->setting.flag &= ~firewall_main_flag_operation_restart_e;
+        main->setting.flag &= ~firewall_main_flag_operation_show_e;
+        main->setting.flag &= ~firewall_main_flag_operation_start_e;
+        main->setting.flag &= ~firewall_main_flag_operation_stop_e;
+
+        main->setting.flag |= firewall_main_flag_operation_lock_e;
+
+        at = main->program.parameters.array[firewall_parameter_operation_lock_e].values.array[0];
+      }
+    }
+
+    if (main->program.parameters.array[firewall_parameter_operation_show_e].result & f_console_result_found_e) {
+      if (!(main->setting.flag & firewall_main_flag_operation_e) || (main->program.parameters.array[at].values.array[0] > main->program.parameters.array[firewall_parameter_operation_show_e].values.array[0])) {
+        main->setting.flag &= ~firewall_main_flag_operation_lock_e;
+        main->setting.flag &= ~firewall_main_flag_operation_restart_e;
+        main->setting.flag &= ~firewall_main_flag_operation_start_e;
+        main->setting.flag &= ~firewall_main_flag_operation_stop_e;
+
+        main->setting.flag |= firewall_main_flag_operation_show_e;
+      }
+    }
+
+    if (main->program.pipe & fll_program_data_pipe_input_e) {
+      main->setting.flag |= firewall_main_flag_pipe_e;
+    }
+    else {
+      main->setting.flag &= ~firewall_main_flag_pipe_e;
+    }
+
+    if (main->setting.flag & firewall_main_flag_operation_show_e) {
+      if (main->parameters.remaining.used) {
+        main->setting.flag &= ~firewall_main_flag_operation_show_filter_nat_mangle_e;
+
+        for (at = 0; at < main->parameters.remaining.used; ++at) {
+
+          if (firewall_signal_check(main)) return;
+
+          if (f_compare_dynamic(firewall_show_nat_s, data.argv[main->program.parameters.remaining.array[at]]) == F_equal_to) {
+            main->setting.flag |= firewall_main_flag_operation_show_nat_e;
+          }
+          else if (f_compare_dynamic(firewall_show_mangle_s, data.argv[main->program.parameters.remaining.array[at]]) == F_equal_to) {
+            main->setting.flag |= firewall_main_flag_operation_show_mangle_e;
+          }
+          else if (f_compare_dynamic(firewall_show_fillter_s, data.argv[main->program.parameters.remaining.array[at]]) == F_equal_to) {
+            main->setting.flag |= firewall_main_flag_operation_show_filter_e;
+          }
+          else {
+            firewall_print_warning_show_option_unknown(&main->warning, data.argv[main->program.parameters.remaining.array[at]]);
+          }
+        } // for
+      }
+      else {
+        main->setting.flag |= firewall_main_flag_operation_show_filter_nat_mangle_e;
+      }
+    }
+  }
+#endif // _di_firewall_setting_load_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/common.h b/level_3/firewall/c/main/common.h
new file mode 100644 (file)
index 0000000..f262d22
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the common data structures.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_common_h
+#define _firewall_common_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately returns without doing anything.
+ *
+ * @param arguments
+ *   The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ *   The main program data and settings.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *
+ *     Errors (with error bit) from: f_console_parameter_process().
+ *     Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_firewall_setting_load_
+  extern void firewall_setting_load(const f_console_arguments_t arguments, firewall_main_t * const main);
+#endif // _di_firewall_setting_load_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_common_h
diff --git a/level_3/firewall/c/main/common/define.c b/level_3/firewall/c/main/common/define.c
new file mode 100644 (file)
index 0000000..9bcd373
--- /dev/null
@@ -0,0 +1,9 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/common/define.h b/level_3/firewall/c/main/common/define.h
new file mode 100644 (file)
index 0000000..9045d04
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the common define types.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_common_define_h
+#define _firewall_common_define_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The program allocation defines.
+ *
+ * firewall_allocation_*_d:
+ *   - console: An allocation step used for small buffers specifically for console parameter.
+ *   - large:   An allocation step used for buffers that are anticipated to have large buffers.
+ *   - pipe:    A buffer size used for processing piped data.
+ *   - small:   An allocation step used for buffers that are anticipated to have small buffers.
+ */
+#ifndef _di_firewall_allocation_d_
+  #define firewall_allocation_console_d 4
+  #define firewall_allocation_large_d   256
+  #define firewall_allocation_pipe_d    16384
+  #define firewall_allocation_small_d   16
+#endif // _di_firewall_allocation_d_
+
+/**
+ * The program signal defines.
+ *
+ * firewall_signal_*_d:
+ *   - check:          Number of iterations before performing signal check in non-threaded signal handling.
+ *   - check_failsafe: When using threads, how many consecutive failures to check signal before aborting (as a recursion failsafe).
+ *   - check_tiny:     The tiny check.
+ *   - check_short:    The short signal check.
+ */
+#ifndef _di_firewall_signal_d_
+  #define firewall_signal_check_d          500000
+  #define firewall_signal_check_failsafe_d 20000
+  #define firewall_signal_check_tiny_d     4
+  #define firewall_signal_check_short_d    16
+#endif // _di_firewall_signal_d_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_common_define_h
diff --git a/level_3/firewall/c/main/common/enumeration.c b/level_3/firewall/c/main/common/enumeration.c
new file mode 100644 (file)
index 0000000..9bcd373
--- /dev/null
@@ -0,0 +1,9 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/common/enumeration.h b/level_3/firewall/c/main/common/enumeration.h
new file mode 100644 (file)
index 0000000..d04d62f
--- /dev/null
@@ -0,0 +1,162 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the common enumeration types.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_common_enumeration_h
+#define _firewall_common_enumeration_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Flags passed to the main function or program.
+ *
+ * firewall_main_flag_*_e:
+ *   - none:                             No flags set.
+ *   - copyright:                        Print copyright.
+ *   - help:                             Print help.
+ *   - operation:                        A helper flag representing every operation flag bit being set.
+ *   - operation_lock:                   Perform the lock operation.
+ *   - operation_restart:                Perform the restart operation.
+ *   - operation_show:                   Perform the show operation.
+ *   - operation_show_nat:               For the show operation, show nat.
+ *   - operation_show_mangle:            For the show operation, show mangle.
+ *   - operation_show_filter:            For the show operation, show ports.
+ *   - operation_show_filter_nat_mangle: A helper flag representing the show nat, show mangle, and short port flags set.
+ *   - operation_start:                  Perform the start operation.
+ *   - operation_start_restart:          A helper flag representing both the start and restart operation flag set.
+ *   - operation_stop:                   Perform the stop operation.
+ *   - operation_stop_restart:           A helper flag representing both the stop and restart operation flag set.
+ *   - operation_stop_restart_lock:      A helper flag representing both the stop, restart, and lock operation flag set.
+ *   - pipe:                             Use the input pipe.
+ *   - print_first:                      When set, print new line to message output on program begin after loading settings.
+ *   - print_last:                       When set, print new line to message output on program end.
+ *   - version:                          Print version.
+ *   - version_copyright_help:           A helper flag representing version, copyright, and help flag bits being set.
+ */
+#ifndef _di_firewall_main_flag_e_
+  enum {
+    firewall_main_flag_none_e                             = 0x0,
+    firewall_main_flag_copyright_e                        = 0x1,
+    firewall_main_flag_help_e                             = 0x2,
+    firewall_main_flag_operation_e                        = 0x4,
+    firewall_main_flag_operation_lock_e                   = 0x8,
+    firewall_main_flag_operation_restart_e                = 0x10,
+    firewall_main_flag_operation_show_e                   = 0x20,
+    firewall_main_flag_operation_show_nat_e               = 0x40,
+    firewall_main_flag_operation_show_mangle_e            = 0x80,
+    firewall_main_flag_operation_show_filter_e            = 0x100,
+    firewall_main_flag_operation_show_filter_nat_mangle_e = 0x1c0,
+    firewall_main_flag_operation_start_e                  = 0x200,
+    firewall_main_flag_operation_start_restart_e          = 0x210,
+    firewall_main_flag_operation_stop_e                   = 0x400,
+    firewall_main_flag_operation_stop_restart_e           = 0x410,
+    firewall_main_flag_operation_stop_restart_lock_e      = 0x418,
+    firewall_main_flag_pipe_e                             = 0x800,
+    firewall_main_flag_print_first_e                      = 0x1000,
+    firewall_main_flag_print_last_e                       = 0x2000,
+    firewall_main_flag_version_e                          = 0x4000,
+    firewall_main_flag_version_copyright_help_e           = 0x4003,
+  }; // enum
+#endif // _di_firewall_main_flag_e_
+
+/**
+ * Flags representing the current state of the processed rule.
+ *
+ * firewall_data_flag_*_e:
+ *   - none:   No flags set.
+ *   - global: The current processed rule is global.
+ *   - local:  The current processed rule is lock.
+ *   - main:   The current processed rule is main.
+ *   - stop:   The current processed rule is stop.
+ */
+#ifndef _di_firewall_data_flag_e_
+  enum {
+    firewall_data_is_none_e   = 0x0,
+    firewall_data_is_global_e = 0x1,
+    firewall_data_is_lock_e   = 0x2,
+    firewall_data_is_main_e   = 0x4,
+    firewall_data_is_stop_e   = 0x8,
+  }; // enum
+#endif // _di_firewall_data_flag_e_
+
+/**
+ * Flags representing the existence of reserved sets.
+ *
+ * firewall_data_flag_*_e:
+ *   - none:  No flags set.
+ *   - local: The current processed rule is lock.
+ *   - main:  The current processed rule is main.
+ *   - stop:  The current processed rule is stop.
+ */
+#ifndef _di_firewall_data_flag_e_
+  enum {
+    firewall_data_has_none_e   = 0x0,
+    firewall_data_has_lock_e   = 0x1,
+    firewall_data_has_main_e   = 0x2,
+    firewall_data_has_stop_e   = 0x4,
+  }; // enum
+#endif // _di_firewall_data_flag_e_
+
+/**
+ * The main program parameters.
+ */
+#ifndef _di_firewall_parameter_e_
+  enum {
+    fake_parameter_operation_build_e = f_console_standard_parameter_last_e,
+    fake_parameter_operation_clean_e,
+    fake_parameter_operation_make_e,
+    fake_parameter_operation_skeleton_e,
+  }; // enum
+
+  #define firewall_console_parameter_t_initialize \
+    { \
+      macro_fll_program_console_parameter_standard_initialize, \
+      \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_build_s,    0, f_console_flag_simple_e), \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_clean_s,    0, f_console_flag_simple_e), \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_make_s,     0, f_console_flag_simple_e), \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_skeleton_s, 0, f_console_flag_simple_e), \
+    }
+
+  #define firewall_parameter_total_d (f_console_parameter_state_type_total_d + 4)
+#endif // _di_firewall_parameter_e_
+
+/**
+ * Flags for fine-tuned print control.
+ *
+ * firewall_print_flag_*_e:
+ *   - none:    No flags set.
+ *   - debug:   Stream is for debug printing.
+ *   - error:   Stream is for error printing.
+ *   - in:      Stream is a source file.
+ *   - message: Stream is for message printing.
+ *   - out:     Stream is a destination file.
+ *   - warning: Stream is for warning printing.
+ */
+#ifndef _di_firewall_print_flag_e_
+  enum {
+    firewall_print_flag_none_e    = 0x0,
+    firewall_print_flag_debug_e   = 0x1,
+    firewall_print_flag_error_e   = 0x2,
+    firewall_print_flag_file_e    = 0x4,
+    firewall_print_flag_in_e      = 0x8,
+    firewall_print_flag_out_e     = 0x10,
+    firewall_print_flag_message_e = 0x20,
+    firewall_print_flag_warning_e = 0x40,
+  }; // enum
+#endif // _di_firewall_print_flag_e_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_common_enumeration_h
diff --git a/level_3/firewall/c/main/common/print.c b/level_3/firewall/c/main/common/print.c
new file mode 100644 (file)
index 0000000..0567f9f
--- /dev/null
@@ -0,0 +1,21 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_f_a_
+  const f_string_t firewall_f_a[] = {
+    "f_console_parameter_process",
+    "f_directory_list",
+    "f_fss_apply_delimit",
+    "firewall_operate_process_rules_perform",
+    "fll_fss_extended_read",
+    "fll_program_parameter_process_context_standard",
+    "fll_program_parameter_process_verbosity_standard",
+  };
+#endif // _di_firewall_f_a_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/common/print.h b/level_3/firewall/c/main/common/print.h
new file mode 100644 (file)
index 0000000..85b7a87
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the common print functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_common_print_h
+#define _firewall_common_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A special array of strings intended for representing funciton names.
+ *
+ * These are primarily used for printing errors with the function names.
+ *
+ * The macro macro_firewall_f() is used to reference the array index by the enum name.
+ *
+ * macro_firewall_f():
+ *   - name: The name of the function.
+ */
+#ifndef _di_firewall_f_a_
+  extern const f_string_t firewall_f_a[];
+
+  #define macro_firewall_f(name) firewall_f_a[firewall_f_##name##_e]
+#endif // _di_firewall_f_a_
+
+/**
+ * An enum representing specific indexes within the above array.
+ *
+ * This is a convenience enum used to make code slightly more readable.
+ */
+#ifndef _di_firewall_f_e_
+  enum {
+    firewall_f_f_console_parameter_process_e,
+    firewall_f_f_directory_list_e,
+    firewall_f_f_fss_apply_delimit_e,
+    firewall_f_firewall_operate_process_rules_perform_e,
+    firewall_f_fll_fss_extended_read_e,
+    firewall_f_fll_program_parameter_process_context_standard_e,
+    firewall_f_fll_program_parameter_process_verbosity_standard_e,
+  }; // enum
+#endif // _di_firewall_f_e_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_common_print_h
similarity index 57%
rename from level_3/firewall/c/common.c
rename to level_3/firewall/c/main/common/string.c
index 6b19cf7..a71c403 100644 (file)
@@ -1,4 +1,4 @@
-#include "firewall.h"
+#include "../firewall.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -17,26 +17,16 @@ extern "C" {
   const f_string_static_t firewall_program_help_parameters_s = macro_f_string_static_t_initialize_1(FIREWALL_program_help_parameters_s, 0, FIREWALL_program_help_parameters_s_length);
 #endif // _di_firewall_program_help_parameters_s_
 
-#ifndef _di_firewall_path_s_
-  const f_string_static_t firewall_file_first_s = macro_f_string_static_t_initialize_1(FIREWALL_file_first_s, 0, FIREWALL_file_first_s_length);
-  const f_string_static_t firewall_file_last_s = macro_f_string_static_t_initialize_1(FIREWALL_file_last_s, 0, FIREWALL_file_last_s_length);
-  const f_string_static_t firewall_file_other_s = macro_f_string_static_t_initialize_1(FIREWALL_file_other_s, 0, FIREWALL_file_other_s_length);
-  const f_string_static_t firewall_file_suffix_s = macro_f_string_static_t_initialize_1(FIREWALL_file_suffix_s, 0, FIREWALL_file_suffix_s_length);
-
-  const f_string_static_t firewall_network_path_s = macro_f_string_static_t_initialize_1(FIREWALL_network_path_s, 0, FIREWALL_network_path_s_length);
-  const f_string_static_t firewall_network_devices_s = macro_f_string_static_t_initialize_1(FIREWALL_network_devices_s, 0, FIREWALL_network_devices_s_length);
-#endif // _di_firewall_path_s_
-
-#ifndef _di_firewall_d_
+#ifndef _di_firewall_s_
   const f_string_static_t firewall_action_s = macro_f_string_static_t_initialize_1(FIREWALL_action_s, 0, FIREWALL_action_s_length);
   const f_string_static_t firewall_action_append_s = macro_f_string_static_t_initialize_1(FIREWALL_action_append_s, 0, FIREWALL_action_append_s_length);
   const f_string_static_t firewall_action_insert_s = macro_f_string_static_t_initialize_1(FIREWALL_action_insert_s, 0, FIREWALL_action_insert_s_length);
   const f_string_static_t firewall_action_policy_s = macro_f_string_static_t_initialize_1(FIREWALL_action_policy_s, 0, FIREWALL_action_policy_s_length);
   const f_string_static_t firewall_action_none_s = macro_f_string_static_t_initialize_1(FIREWALL_action_none_s, 0, FIREWALL_action_none_s_length);
 
-  const f_string_static_t firewall_action_append_command_s = macro_f_string_static_t_initialize_1(FIREWALL_action_append_command_s, 0, FIREWALL_action_append_command_s_length);
-  const f_string_static_t firewall_action_insert_command_s = macro_f_string_static_t_initialize_1(FIREWALL_action_insert_command_s, 0, FIREWALL_action_insert_command_s_length);
-  const f_string_static_t firewall_action_policy_command_s = macro_f_string_static_t_initialize_1(FIREWALL_action_policy_command_s, 0, FIREWALL_action_policy_command_s_length);
+  const f_string_static_t firewall_action_append_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_action_append_operation_s, 0, FIREWALL_action_append_operation_s_length);
+  const f_string_static_t firewall_action_insert_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_action_insert_operation_s, 0, FIREWALL_action_insert_operation_s_length);
+  const f_string_static_t firewall_action_policy_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_action_policy_operation_s, 0, FIREWALL_action_policy_operation_s_length);
 
   const f_string_static_t firewall_chain_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_s, 0, FIREWALL_chain_s_length);
   const f_string_static_t firewall_chain_forward_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_forward_s, 0, FIREWALL_chain_forward_s_length);
@@ -47,23 +37,23 @@ extern "C" {
   const f_string_static_t firewall_chain_postrouting_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_postrouting_s, 0, FIREWALL_chain_postrouting_s_length);
   const f_string_static_t firewall_chain_prerouting_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_prerouting_s, 0, FIREWALL_chain_prerouting_s_length);
 
-  const f_string_static_t firewall_chain_create_command_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_create_command_s, 0, FIREWALL_chain_create_command_s_length);
-  const f_string_static_t firewall_chain_delete_command_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_delete_command_s, 0, FIREWALL_chain_delete_command_s_length);
-  const f_string_static_t firewall_chain_flush_command_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_flush_command_s, 0, FIREWALL_chain_flush_command_s_length);
+  const f_string_static_t firewall_chain_create_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_create_operation_s, 0, FIREWALL_chain_create_operation_s_length);
+  const f_string_static_t firewall_chain_delete_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_delete_operation_s, 0, FIREWALL_chain_delete_operation_s_length);
+  const f_string_static_t firewall_chain_flush_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_chain_flush_operation_s, 0, FIREWALL_chain_flush_operation_s_length);
 
-  const f_string_static_t firewall_command_start_s = macro_f_string_static_t_initialize_1(FIREWALL_command_start_s, 0, FIREWALL_command_start_s_length);
-  const f_string_static_t firewall_command_stop_s = macro_f_string_static_t_initialize_1(FIREWALL_command_stop_s, 0, FIREWALL_command_stop_s_length);
-  const f_string_static_t firewall_command_restart_s = macro_f_string_static_t_initialize_1(FIREWALL_command_restart_s, 0, FIREWALL_command_restart_s_length);
-  const f_string_static_t firewall_command_lock_s = macro_f_string_static_t_initialize_1(FIREWALL_command_lock_s, 0, FIREWALL_command_lock_s_length);
-  const f_string_static_t firewall_command_show_s = macro_f_string_static_t_initialize_1(FIREWALL_command_show_s, 0, FIREWALL_command_show_s_length);
+  const f_string_static_t firewall_operation_start_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_start_s, 0, FIREWALL_operation_start_s_length);
+  const f_string_static_t firewall_operation_stop_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_stop_s, 0, FIREWALL_operation_stop_s_length);
+  const f_string_static_t firewall_operation_restart_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_restart_s, 0, FIREWALL_operation_restart_s_length);
+  const f_string_static_t firewall_operation_lock_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_lock_s, 0, FIREWALL_operation_lock_s_length);
+  const f_string_static_t firewall_operation_show_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_show_s, 0, FIREWALL_operation_show_s_length);
 
   const f_string_static_t firewall_device_s = macro_f_string_static_t_initialize_1(FIREWALL_device_s, 0, FIREWALL_device_s_length);
   const f_string_static_t firewall_device_all_s = macro_f_string_static_t_initialize_1(FIREWALL_device_all_s, 0, FIREWALL_device_all_s_length);
   const f_string_static_t firewall_device_this_s = macro_f_string_static_t_initialize_1(FIREWALL_device_this_s, 0, FIREWALL_device_this_s_length);
   const f_string_static_t firewall_device_loop_s = macro_f_string_static_t_initialize_1(FIREWALL_device_loop_s, 0, FIREWALL_device_loop_s_length);
 
-  const f_string_static_t firewall_device_input_command_s = macro_f_string_static_t_initialize_1(FIREWALL_device_input_command_s, 0, FIREWALL_device_input_command_s_length);
-  const f_string_static_t firewall_device_output_command_s = macro_f_string_static_t_initialize_1(FIREWALL_device_output_command_s, 0, FIREWALL_device_output_command_s_length);
+  const f_string_static_t firewall_device_input_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_device_input_operation_s, 0, FIREWALL_device_input_operation_s_length);
+  const f_string_static_t firewall_device_output_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_device_output_operation_s, 0, FIREWALL_device_output_operation_s_length);
 
   const f_string_static_t firewall_direction_s = macro_f_string_static_t_initialize_1(FIREWALL_direction_s, 0, FIREWALL_direction_s_length);
   const f_string_static_t firewall_direction_input_s = macro_f_string_static_t_initialize_1(FIREWALL_direction_input_s, 0, FIREWALL_direction_input_s_length);
@@ -81,14 +71,14 @@ extern "C" {
   const f_string_static_t firewall_ip_list_destination_action_s = macro_f_string_static_t_initialize_1(FIREWALL_ip_list_destination_action_s, 0, FIREWALL_ip_list_destination_action_s_length);
 
   const f_string_static_t firewall_protocol_s = macro_f_string_static_t_initialize_1(FIREWALL_protocol_s, 0, FIREWALL_protocol_s_length);
-  const f_string_static_t firewall_protocol_command_s = macro_f_string_static_t_initialize_1(FIREWALL_protocol_command_s, 0, FIREWALL_protocol_command_s_length);
+  const f_string_static_t firewall_protocol_operation_s = macro_f_string_static_t_initialize_1(FIREWALL_protocol_operation_s, 0, FIREWALL_protocol_operation_s_length);
   const f_string_static_t firewall_protocol_none_s = macro_f_string_static_t_initialize_1(FIREWALL_protocol_none_s, 0, FIREWALL_protocol_none_s_length);
 
   const f_string_static_t firewall_rule_s = macro_f_string_static_t_initialize_1(FIREWALL_rule_s, 0, FIREWALL_rule_s_length);
 
+  const f_string_static_t firewall_show_filter_s = macro_f_string_static_t_initialize_1(FIREWALL_show_filter_s, 0, FIREWALL_show_filter_s_length);
   const f_string_static_t firewall_show_mangle_s = macro_f_string_static_t_initialize_1(FIREWALL_show_mangle_s, 0, FIREWALL_show_mangle_s_length);
   const f_string_static_t firewall_show_nat_s = macro_f_string_static_t_initialize_1(FIREWALL_show_nat_s, 0, FIREWALL_show_nat_s_length);
-  const f_string_static_t firewall_show_ports_s = macro_f_string_static_t_initialize_1(FIREWALL_show_ports_s, 0, FIREWALL_show_ports_s_length);
 
   const f_string_static_t firewall_show_parameter_exact_s = macro_f_string_static_t_initialize_1(FIREWALL_show_parameter_exact_s, 0, FIREWALL_show_parameter_exact_s_length);
   const f_string_static_t firewall_show_parameter_verbose_s = macro_f_string_static_t_initialize_1(FIREWALL_show_parameter_verbose_s, 0, FIREWALL_show_parameter_verbose_s_length);
@@ -101,109 +91,35 @@ extern "C" {
   const f_string_static_t firewall_tool_ip6tables_s = macro_f_string_static_t_initialize_1(FIREWALL_tool_ip6tables_s, 0, FIREWALL_tool_ip6tables_s_length);
   const f_string_static_t firewall_tool_ip46tables_s = macro_f_string_static_t_initialize_1(FIREWALL_tool_ip46tables_s, 0, FIREWALL_tool_ip46tables_s_length);
   const f_string_static_t firewall_tool_ipset_s = macro_f_string_static_t_initialize_1(FIREWALL_tool_ipset_s, 0, FIREWALL_tool_ipset_s_length);
-#endif // _di_firewall_d_
-
-#ifndef _di_firewall_setting_delete_
-  f_status_t firewall_setting_delete(firewall_setting_t * const setting) {
-
-    if (!setting) return F_status_set_error(F_parameter);
-
-    return F_okay;
-  }
-#endif // _di_firewall_setting_delete_
-
-#ifndef _di_firewall_setting_load_
-  void firewall_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, firewall_setting_t * const setting, f_state_t * const state) {
-
-    if (!main) return;
-
-    main->setting.flag = 0;
-
-    main->setting.state.status = f_console_parameter_process(state, arguments, &main->program.parameters, &main->setting.state, 0);
-
-    // Identify and process first/last parameters.
-    if (main->program.parameters.array[f_console_standard_parameter_line_first_no_e].result & f_console_result_found_e) {
-      main->setting.flag &= ~firewall_main_flag_print_first_e;
-    }
-    else {
-      main->setting.flag |= firewall_main_flag_print_first_e;
-    }
-
-    if (main->program.parameters.array[f_console_standard_parameter_line_last_no_e].result & f_console_result_found_e) {
-      main->setting.flag &= ~firewall_main_flag_print_last_e;
-    }
-    else {
-      main->setting.flag |= firewall_main_flag_print_last_e;
-    }
-
-    if (F_status_is_error(main->setting.state.status)) {
-      fll_error_print(&main->program.error, F_status_set_fine(main->setting.state.status), "f_console_parameter_process", fll_error_file_flag_fallback_e);
-
-      if (main->program.error.verbosity > f_console_verbosity_quiet_e) {
-        fll_print_dynamic_raw(f_string_eol_s, main->program.error);
-      }
-
-      return;
-    }
-
-    main->setting.state.status = fll_program_parameter_process_context_standard(F_true, &main->program);
+#endif // _di_firewall_s_
 
-    if (F_status_is_error(main->setting.state.status)) {
-      fll_error_print(&main->program.error, F_status_set_fine(main->setting.state.status), "fll_program_parameter_process_context_standard", fll_error_file_flag_fallback_e);
+#ifndef _di_firewall_operation_s_
+  const f_string_static_t firewall_operation_start_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_start_s, 0, FIREWALL_operation_start_s_length);
+  const f_string_static_t firewall_operation_stop_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_stop_s, 0, FIREWALL_operation_stop_s_length);
+  const f_string_static_t firewall_operation_restart_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_restart_s, 0, FIREWALL_operation_restart_s_length);
+  const f_string_static_t firewall_operation_lock_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_lock_s, 0, FIREWALL_operation_lock_s_length);
+  const f_string_static_t firewall_operation_show_s = macro_f_string_static_t_initialize_1(FIREWALL_operation_show_s, 0, FIREWALL_operation_show_s_length);
+#endif // _di_firewall_operation_s_
 
-      if (main->program.error.verbosity > f_console_verbosity_quiet_e) {
-        fll_print_dynamic_raw(f_string_eol_s, main->program.error);
-      }
-
-      return;
-    }
-
-    main->setting.state.status = fll_program_parameter_process_verbosity_standard(F_true, &main->program);
-
-    if (F_status_is_error(main->setting.state.status)) {
-      fll_error_print(&main->program.error, F_status_set_fine(main->setting.state.status), "fll_program_parameter_process_verbosity_standard", fll_error_file_flag_fallback_e);
-
-      if (main->program.error.verbosity > f_console_verbosity_quiet_e) {
-        fll_print_dynamic_raw(f_string_eol_s, main->program.error);
-      }
-
-      return;
-    }
-
-    main->program.output.to.id = F_type_descriptor_output_d;
-    main->program.output.to.stream = F_type_output_d;
-    main->program.output.to.flag = F_file_flag_create_d | F_file_flag_write_only_d | F_file_flag_append_d;
-
-    if (main->program.parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) {
-      main->setting.flag |= firewall_main_flag_help_e;
-
-      return;
-    }
-
-    if (main->program.parameters.array[f_console_standard_parameter_version_e].result & f_console_result_found_e) {
-      main->setting.flag |= firewall_main_flag_version_e;
-
-      return;
-    }
-
-    f_string_static_t * const args = main->program.parameters.arguments.array;
-
-    if (main->program.parameters.array[firewall_parameter_strip_invalid_e].result & f_console_result_found_e) {
-      main->setting.flag |= firewall_main_flag_strip_invalid_e;
-    }
-  }
-#endif // _di_firewall_setting_load_
-
-#ifndef _di_firewall_setting_unload_
-  f_status_t firewall_setting_unload(firewall_main_t * const main) {
+#ifndef _di_firewall_path_s_
+  const f_string_static_t firewall_file_first_s = macro_f_string_static_t_initialize_1(FIREWALL_file_first_s, 0, FIREWALL_file_first_s_length);
+  const f_string_static_t firewall_file_last_s = macro_f_string_static_t_initialize_1(FIREWALL_file_last_s, 0, FIREWALL_file_last_s_length);
+  const f_string_static_t firewall_file_other_s = macro_f_string_static_t_initialize_1(FIREWALL_file_other_s, 0, FIREWALL_file_other_s_length);
+  const f_string_static_t firewall_file_suffix_s = macro_f_string_static_t_initialize_1(FIREWALL_file_suffix_s, 0, FIREWALL_file_suffix_s_length);
 
-    if (!main) return F_status_set_error(F_parameter);
+  const f_string_static_t firewall_network_path_s = macro_f_string_static_t_initialize_1(FIREWALL_network_path_s, 0, FIREWALL_network_path_s_length);
+  const f_string_static_t firewall_network_devices_s = macro_f_string_static_t_initialize_1(FIREWALL_network_devices_s, 0, FIREWALL_network_devices_s_length);
+#endif // _di_firewall_path_s_
 
-    firewall_setting_delete(&main->setting);
+#ifndef _di_firewall_show_s_
+  const f_string_static_t firewall_show_filter_s = macro_f_string_static_t_initialize_1(FIREWALL_show_filter_s, 0, FIREWALL_show_filter_s_length);
+  const f_string_static_t firewall_show_mangle_s = macro_f_string_static_t_initialize_1(FIREWALL_show_mangle_s, 0, FIREWALL_show_mangle_s_length);
+  const f_string_static_t firewall_show_nat_s = macro_f_string_static_t_initialize_1(FIREWALL_show_nat_s, 0, FIREWALL_show_nat_s_length);
 
-    return F_okay;
-  }
-#endif // _di_firewall_setting_unload_
+  const f_string_static_t firewall_show_bars_26_s = macro_f_string_static_t_initialize_1(FIREWALL_show_bars_26_s, 0, FIREWALL_show_bars_26_s_length);
+  const f_string_static_t firewall_show_bars_27_s = macro_f_string_static_t_initialize_1(FIREWALL_show_bars_27_s, 0, FIREWALL_show_bars_27_s_length);
+  const f_string_static_t firewall_show_bars_28_s = macro_f_string_static_t_initialize_1(FIREWALL_show_bars_28_s, 0, FIREWALL_show_bars_28_s_length);
+#endif // _di_firewall_show_s_
 
 #ifdef __cplusplus
 } // extern "C"
similarity index 50%
rename from level_3/firewall/c/common.h
rename to level_3/firewall/c/main/common/string.h
index eda13ed..e9c3df3 100644 (file)
@@ -5,12 +5,12 @@
  * API Version: 0.7
  * Licenses: lgpl-2.1-or-later
  *
- * Provides the common data structures.
+ * Provides the common string structures.
  *
  * This is auto-included and should not need to be explicitly included.
  */
-#ifndef _firewall_common_h
-#define _firewall_common_h
+#ifndef _firewall_common_string_h
+#define _firewall_common_string_h
 
 #ifdef __cplusplus
 extern "C" {
@@ -63,70 +63,25 @@ extern "C" {
  * The program help related data.
  */
 #ifndef _di_firewall_program_help_parameters_s_
-  #define FIREWALL_program_help_parameters_s "command"
-  #define FIREWALL_program_help_parameters_s_length 7
+  #define FIREWALL_program_help_parameters_s "operation"
+  #define FIREWALL_program_help_parameters_s_length 9
 
   extern const f_string_static_t firewall_program_help_parameters_s;
 #endif // _di_firewall_program_help_parameters_s_
 
 /**
- * The program paths.
+ * The firewall strings.
  */
-#ifndef _di_firewall_path_s_
-  #define FIREWALL_file_first_s  "firewall-first"
-  #define FIREWALL_file_last_s   "firewall-last"
-  #define FIREWALL_file_other_s  "firewall-other"
-  #define FIREWALL_file_suffix_s "-firewall"
-
-  #define FIREWALL_network_path_s    "/etc/network/"
-  #define FIREWALL_network_devices_s "/sys/class/net/"
-
-  #define FIREWALL_file_first_s_length   14
-  #define FIREWALL_file_last_s_length    13
-  #define FIREWALL_file_other_s_length   14
-  #define FIREWALL_file_suffix_s_length  9
-
-  #define FIREWALL_network_path_s_length    13
-  #define FIREWALL_network_devices_s_length 15
-
-  extern const f_string_static_t firewall_file_first_s;
-  extern const f_string_static_t firewall_file_last_s;
-  extern const f_string_static_t firewall_file_other_s;
-  extern const f_string_static_t firewall_file_suffix_s;
-
-  extern const f_string_static_t firewall_network_path_s;
-  extern const f_string_static_t firewall_network_devices_s;
-#endif // _di_firewall_path_s_
-
-/**
- * The program defines.
- *
- * firewall_*_d:
- *   - allocation_console: An allocation step used for small buffers specifically for console parameter.
- *   - allocation_large:   An allocation step used for buffers that are anticipated to have large buffers.
- *   - allocation_small:   An allocation step used for buffers that are anticipated to have small buffers.
- *   - signal_check:       Number of iterations before performing signal check in non-threaded signal handling.
- */
-#ifndef _di_firewall_d_
-  #define firewall_allocation_console_d 4
-  #define firewall_allocation_large_d   256
-  #define firewall_allocation_small_d   16
-  #define firewall_signal_check_d       20000
-#endif // _di_firewall_d_
-
-/**
- * The main program parameters.
- */
-#ifndef _di_firewall_parameter_d_
+#ifndef _di_firewall_s_
   #define FIREWALL_action_s        "action"
   #define FIREWALL_action_append_s "append"
   #define FIREWALL_action_insert_s "insert"
   #define FIREWALL_action_policy_s "policy"
   #define FIREWALL_action_none_s   "none"
 
-  #define FIREWALL_action_append_command_s "-A"
-  #define FIREWALL_action_insert_command_s "-I"
-  #define FIREWALL_action_policy_command_s "-P"
+  #define FIREWALL_action_append_operation_s "-A"
+  #define FIREWALL_action_insert_operation_s "-I"
+  #define FIREWALL_action_policy_operation_s "-P"
 
   #define FIREWALL_chain_s             "chain"
   #define FIREWALL_chain_forward_s     "FORWARD"
@@ -137,23 +92,23 @@ extern "C" {
   #define FIREWALL_chain_postrouting_s "POSTROUTING"
   #define FIREWALL_chain_prerouting_s  "PREROUTING"
 
-  #define FIREWALL_chain_create_command_s "-N"
-  #define FIREWALL_chain_delete_command_s "-X"
-  #define FIREWALL_chain_flush_command_s  "-F"
+  #define FIREWALL_chain_create_operation_s "-N"
+  #define FIREWALL_chain_delete_operation_s "-X"
+  #define FIREWALL_chain_flush_operation_s  "-F"
 
-  #define FIREWALL_command_start_s   "start"
-  #define FIREWALL_command_stop_s    "stop"
-  #define FIREWALL_command_restart_s "restart"
-  #define FIREWALL_command_lock_s    "lock"
-  #define FIREWALL_command_show_s    "show"
+  #define FIREWALL_operation_start_s   "start"
+  #define FIREWALL_operation_stop_s    "stop"
+  #define FIREWALL_operation_restart_s "restart"
+  #define FIREWALL_operation_lock_s    "lock"
+  #define FIREWALL_operation_show_s    "show"
 
   #define FIREWALL_device_s      "device"
   #define FIREWALL_device_all_s  "all"
   #define FIREWALL_device_this_s "this"
   #define FIREWALL_device_loop_s "lo"
 
-  #define FIREWALL_device_input_command_s  "-i"
-  #define FIREWALL_device_output_command_s "-o"
+  #define FIREWALL_device_input_operation_s  "-i"
+  #define FIREWALL_device_output_operation_s "-o"
 
   #define FIREWALL_direction_s        "direction"
   #define FIREWALL_direction_input_s  "input"
@@ -171,14 +126,14 @@ extern "C" {
   #define FIREWALL_ip_list_destination_action_s "-d"
 
   #define FIREWALL_protocol_s         "protocol"
-  #define FIREWALL_protocol_command_s "-p"
+  #define FIREWALL_protocol_operation_s "-p"
   #define FIREWALL_protocol_none_s    "none"
 
   #define FIREWALL_rule_s "rule"
 
+  #define FIREWALL_show_filter_s "filter"
   #define FIREWALL_show_mangle_s "mangle"
   #define FIREWALL_show_nat_s    "nat"
-  #define FIREWALL_show_ports_s  "ports"
 
   #define FIREWALL_show_parameter_exact_s   "-x"
   #define FIREWALL_show_parameter_verbose_s "-v"
@@ -198,9 +153,9 @@ extern "C" {
   #define FIREWALL_action_policy_s_length 6
   #define FIREWALL_action_none_s_length   4
 
-  #define FIREWALL_action_append_command_s_length 2
-  #define FIREWALL_action_insert_command_s_length 2
-  #define FIREWALL_action_policy_command_s_length 2
+  #define FIREWALL_action_append_operation_s_length 2
+  #define FIREWALL_action_insert_operation_s_length 2
+  #define FIREWALL_action_policy_operation_s_length 2
 
   #define FIREWALL_chain_s_length             5
   #define FIREWALL_chain_forward_s_length     7
@@ -211,23 +166,23 @@ extern "C" {
   #define FIREWALL_chain_postrouting_s_length 12
   #define FIREWALL_chain_prerouting_s_length  11
 
-  #define FIREWALL_chain_create_command_s_length 2
-  #define FIREWALL_chain_delete_command_s_length 2
-  #define FIREWALL_chain_flush_command_s_length  2
+  #define FIREWALL_chain_create_operation_s_length 2
+  #define FIREWALL_chain_delete_operation_s_length 2
+  #define FIREWALL_chain_flush_operation_s_length  2
 
-  #define FIREWALL_command_start_s_length   5
-  #define FIREWALL_command_stop_s_length    4
-  #define FIREWALL_command_restart_s_length 7
-  #define FIREWALL_command_lock_s_length    4
-  #define FIREWALL_command_show_s_length    4
+  #define FIREWALL_operation_start_s_length   5
+  #define FIREWALL_operation_stop_s_length    4
+  #define FIREWALL_operation_restart_s_length 7
+  #define FIREWALL_operation_lock_s_length    4
+  #define FIREWALL_operation_show_s_length    4
 
   #define FIREWALL_device_s_length      6
   #define FIREWALL_device_all_s_length  3
   #define FIREWALL_device_this_s_length 4
   #define FIREWALL_device_loop_s_length 2
 
-  #define FIREWALL_device_input_command_s_length  2
-  #define FIREWALL_device_output_command_s_length 2
+  #define FIREWALL_device_input_operation_s_length  2
+  #define FIREWALL_device_output_operation_s_length 2
 
   #define FIREWALL_direction_s_length        9
   #define FIREWALL_direction_input_s_length  5
@@ -245,14 +200,14 @@ extern "C" {
   #define FIREWALL_ip_list_destination_action_s_length 2
 
   #define FIREWALL_protocol_s_length         8
-  #define FIREWALL_protocol_command_s_length 2
+  #define FIREWALL_protocol_operation_s_length 2
   #define FIREWALL_protocol_none_s_length    4
 
   #define FIREWALL_rule_s_length 4
 
+  #define FIREWALL_show_filter_s_length 6
   #define FIREWALL_show_mangle_s_length 6
   #define FIREWALL_show_nat_s_length    3
-  #define FIREWALL_show_ports_s_length  5
 
   #define FIREWALL_show_parameter_exact_s_length   2
   #define FIREWALL_show_parameter_verbose_s_length 2
@@ -272,9 +227,9 @@ extern "C" {
   extern const f_string_static_t firewall_action_policy_s;
   extern const f_string_static_t firewall_action_none_s;
 
-  extern const f_string_static_t firewall_action_append_command_s;
-  extern const f_string_static_t firewall_action_insert_command_s;
-  extern const f_string_static_t firewall_action_policy_command_s;
+  extern const f_string_static_t firewall_action_append_operation_s;
+  extern const f_string_static_t firewall_action_insert_operation_s;
+  extern const f_string_static_t firewall_action_policy_operation_s;
 
   extern const f_string_static_t firewall_chain_s;
   extern const f_string_static_t firewall_chain_forward_s;
@@ -285,23 +240,23 @@ extern "C" {
   extern const f_string_static_t firewall_chain_postrouting_s;
   extern const f_string_static_t firewall_chain_prerouting_s;
 
-  extern const f_string_static_t firewall_chain_create_command_s;
-  extern const f_string_static_t firewall_chain_delete_command_s;
-  extern const f_string_static_t firewall_chain_flush_command_s;
+  extern const f_string_static_t firewall_chain_create_operation_s;
+  extern const f_string_static_t firewall_chain_delete_operation_s;
+  extern const f_string_static_t firewall_chain_flush_operation_s;
 
-  extern const f_string_static_t firewall_command_start_s;
-  extern const f_string_static_t firewall_command_stop_s;
-  extern const f_string_static_t firewall_command_restart_s;
-  extern const f_string_static_t firewall_command_lock_s;
-  extern const f_string_static_t firewall_command_show_s;
+  extern const f_string_static_t firewall_operation_start_s;
+  extern const f_string_static_t firewall_operation_stop_s;
+  extern const f_string_static_t firewall_operation_restart_s;
+  extern const f_string_static_t firewall_operation_lock_s;
+  extern const f_string_static_t firewall_operation_show_s;
 
   extern const f_string_static_t firewall_device_s;
   extern const f_string_static_t firewall_device_all_s;
   extern const f_string_static_t firewall_device_this_s;
   extern const f_string_static_t firewall_device_loop_s;
 
-  extern const f_string_static_t firewall_device_input_command_s;
-  extern const f_string_static_t firewall_device_output_command_s;
+  extern const f_string_static_t firewall_device_input_operation_s;
+  extern const f_string_static_t firewall_device_output_operation_s;
 
   extern const f_string_static_t firewall_direction_s;
   extern const f_string_static_t firewall_direction_input_s;
@@ -319,14 +274,14 @@ extern "C" {
   extern const f_string_static_t firewall_ip_list_destination_action_s;
 
   extern const f_string_static_t firewall_protocol_s;
-  extern const f_string_static_t firewall_protocol_command_s;
+  extern const f_string_static_t firewall_protocol_operation_s;
   extern const f_string_static_t firewall_protocol_none_s;
 
   extern const f_string_static_t firewall_rule_s;
 
+  extern const f_string_static_t firewall_show_filter_s;
   extern const f_string_static_t firewall_show_mangle_s;
   extern const f_string_static_t firewall_show_nat_s;
-  extern const f_string_static_t firewall_show_ports_s;
 
   extern const f_string_static_t firewall_show_parameter_exact_s;
   extern const f_string_static_t firewall_show_parameter_verbose_s;
@@ -339,187 +294,91 @@ extern "C" {
   extern const f_string_static_t firewall_tool_ip6tables_s;
   extern const f_string_static_t firewall_tool_ip46tables_s;
   extern const f_string_static_t firewall_tool_ipset_s;
-
-  enum {
-    firewall_program_none_e = 1,
-    firewall_program_iptables_e,
-    firewall_program_ip6tables_e,
-    firewall_program_ip46tables_e,
-    firewall_program_ipset_e,
-  }; // enum
-
-  enum {
-    firewall_parameter_command_start_e = f_console_standard_parameter_last_e,
-    firewall_parameter_command_stop_e,
-    firewall_parameter_command_restart_e,
-    firewall_parameter_command_lock_e,
-    firewall_parameter_command_show_e,
-
-    firewall_direction_input_id_e,
-    firewall_direction_output_id_e,
-    firewall_direction_none_id_e,
-
-    firewall_chain_forward_id_e,
-    firewall_chain_custom_id_e,
-    firewall_chain_input_id_e,
-    firewall_chain_none_id_e,
-    firewall_chain_output_id_e,
-    firewall_chain_postrouting_id_e,
-    firewall_chain_prerouting_id_e,
-
-    firewall_action_append_id_e,
-    firewall_action_insert_id_e,
-    firewall_action_policy_id_e,
-    firewall_action_none_id_e,
-  }; // enum
-
-  #define firewall_console_parameter_t_initialize \
-    { \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_help_s,     f_console_standard_long_help_s,     0, f_console_flag_normal_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_light_s,    f_console_standard_long_light_s,    0, f_console_flag_inverse_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_dark_s,     f_console_standard_long_dark_s,     0, f_console_flag_inverse_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, 0, f_console_flag_inverse_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_quiet_s,    f_console_standard_long_quiet_s,    0, f_console_flag_inverse_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_error_s,    f_console_standard_long_error_s,    0, f_console_flag_inverse_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_normal_s,   f_console_standard_long_normal_s,   0, f_console_flag_inverse_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_verbose_s,  f_console_standard_long_verbose_s,  0, f_console_flag_inverse_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_debug_s,    f_console_standard_long_debug_s,    0, f_console_flag_inverse_e), \
-      macro_f_console_parameter_t_initialize_3(f_console_standard_short_version_s,  f_console_standard_long_version_s,  0, f_console_flag_inverse_e), \
-      \
-      macro_f_console_parameter_t_initialize_6(firewall_command_start_s,   0, f_console_flag_simple_e), \
-      macro_f_console_parameter_t_initialize_6(firewall_command_stop_s,    0, f_console_flag_simple_e), \
-      macro_f_console_parameter_t_initialize_6(firewall_command_restart_s, 0, f_console_flag_simple_e), \
-      macro_f_console_parameter_t_initialize_6(firewall_command_lock_s,    0, f_console_flag_simple_e), \
-      macro_f_console_parameter_t_initialize_6(firewall_command_show_s,    0, f_console_flag_simple_e), \
-    }
-
-  #define firewall_parameter_total_d 15
-#endif // _di_firewall_parameter_d_
+#endif // _di_firewall_s_
 
 /**
- * Flags passed to the main function or program.
- *
- * firewall_main_flag_*_e:
- *   - none:          No flags set.
- *   - file_from:     Using a specified source file.
- *   - file_to:       Using a specified destination file.
- *   - header:        Enable printing of headers.
- *   - help:          Print help.
- *   - print_first:   When set, print new line to message output on program begin after loading settings.
- *   - print_last:    When set, print new line to message output on program end.
- *   - separate:      Enable printing of separators.
- *   - strip_invalid: Using strip invalid character mode.
- *   - verify:        Using verify mode.
- *   - version:       Print version.
+ * The main program operations.
  */
-#ifndef _di_firewall_main_flag_e_
-  enum {
-    firewall_main_flag_none_e          = 0x0,
-    firewall_main_flag_file_from_e     = 0x1,
-    firewall_main_flag_file_to_e       = 0x2,
-    firewall_main_flag_header_e        = 0x4,
-    firewall_main_flag_help_e          = 0x8,
-    firewall_main_flag_print_first_e   = 0x20,
-    firewall_main_flag_print_last_e    = 0x40,
-    firewall_main_flag_separate_e      = 0x80,
-    firewall_main_flag_strip_invalid_e = 0x100,
-    firewall_main_flag_verify_e        = 0x200,
-    firewall_main_flag_version_e       = 0x400,
-  }; // enum
-#endif // _di_firewall_main_flag_e_
+#ifndef _di_firewall_operation_s_
+  #define FIREWALL_operation_start_s   "start"
+  #define FIREWALL_operation_stop_s    "stop"
+  #define FIREWALL_operation_restart_s "restart"
+  #define FIREWALL_operation_lock_s    "lock"
+  #define FIREWALL_operation_show_s    "show"
+
+  #define FIREWALL_operation_start_s_length   5
+  #define FIREWALL_operation_stop_s_length    4
+  #define FIREWALL_operation_restart_s_length 7
+  #define FIREWALL_operation_lock_s_length    4
+  #define FIREWALL_operation_show_s_length    4
+
+  extern const f_string_static_t firewall_operation_start_s;
+  extern const f_string_static_t firewall_operation_stop_s;
+  extern const f_string_static_t firewall_operation_restart_s;
+  extern const f_string_static_t firewall_operation_lock_s;
+  extern const f_string_static_t firewall_operation_show_s;
+#endif // _di_firewall_operation_s_
 
 /**
- * The firewall main program settings.
- *
- * This is passed to the program-specific main entry point to designate program settings.
- * These program settings are often processed from the program arguments (often called the command line arguments).
- *
- * flag: Flags passed to the main function.
- *
- * state: The state information.
+ * The program paths.
  */
-#ifndef _di_firewall_setting_t_
-  typedef struct {
-    uint16_t flag;
+#ifndef _di_firewall_path_s_
+  #define FIREWALL_file_first_s  "firewall-first"
+  #define FIREWALL_file_last_s   "firewall-last"
+  #define FIREWALL_file_other_s  "firewall-other"
+  #define FIREWALL_file_suffix_s "-firewall"
 
-    f_state_t state;
-  } firewall_setting_t;
+  #define FIREWALL_network_path_s    "/etc/network/"
+  #define FIREWALL_network_devices_s "/sys/class/net/"
 
-  #define firewall_setting_t_initialize \
-    { \
-      firewall_main_flag_none_e, \
-      f_state_t_initialize, \
-    }
-#endif // _di_firewall_setting_t_
+  #define FIREWALL_file_first_s_length   14
+  #define FIREWALL_file_last_s_length    13
+  #define FIREWALL_file_other_s_length   14
+  #define FIREWALL_file_suffix_s_length  9
 
-/**
- * Delete the program main setting data.
- *
- * @param setting
- *   The program main setting data.
- *
- *   This does not alter setting.state.status.
- *
- * @return
- *   F_okay on success.
- *
- *   F_parameter (with error bit) if a parameter is invalid.
- */
-#ifndef _di_firewall_setting_delete_
-  extern f_status_t firewall_setting_delete(firewall_setting_t * const setting);
-#endif // _di_firewall_setting_delete_
+  #define FIREWALL_network_path_s_length    13
+  #define FIREWALL_network_devices_s_length 15
 
-/**
- * Perform the standard program setting load process.
- *
- * This prints error messages as appropriate.
- *
- * If either main or setting is NULL, then this immediately returns without doing anything.
- *
- * @param arguments
- *   The parameters passed to the process (often referred to as command line arguments).
- * @param main
- *   The main program data.
- * @param setting
- *   The main program settings.
- *
- *   This alters setting.state.status:
- *     F_okay on success.
- *
- *     Errors (with error bit) from: f_console_parameter_process().
- *     Errors (with error bit) from: fll_program_parameter_process_context().
- *
- * @see f_console_parameter_process()
- * @see fll_program_parameter_process_context()
- */
-#ifndef _di_firewall_setting_load_
-  extern void firewall_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, firewall_setting_t * const setting);
-#endif // _di_firewall_setting_load_
+  extern const f_string_static_t firewall_file_first_s;
+  extern const f_string_static_t firewall_file_last_s;
+  extern const f_string_static_t firewall_file_other_s;
+  extern const f_string_static_t firewall_file_suffix_s;
+
+  extern const f_string_static_t firewall_network_path_s;
+  extern const f_string_static_t firewall_network_devices_s;
+#endif // _di_firewall_path_s_
 
 /**
- * Perform the standard program setting unload process.
- *
- * @param main
- *   The main program and setting data.
- *   All buffers are deallocated.
- *
- *   This does not alter main.setting.state.status.
- *
- * @return
- *   F_okay on success.
- *
- *   F_parameter (with error bit) if a parameter is invalid.
- *
- *   Errors (with error bit) from: firewall_setting_delete().
- *
- * @see firewall_setting_delete()
+ * The show option related strings.
  */
-#ifndef _di_firewall_setting_unload_
-  extern f_status_t firewall_setting_unload(firewall_main_t * const main);
-#endif // _di_firewall_setting_unload_
+#ifndef _di_firewall_show_s_
+  #define FIREWALL_show_filter_s "FILTER"
+  #define FIREWALL_show_mangle_s "MANGLE"
+  #define FIREWALL_show_nat_s    "NAT"
+
+  #define FIREWALL_show_bars_26_s "=========================="
+  #define FIREWALL_show_bars_27_s "============================"
+  #define FIREWALL_show_bars_28_s "============================"
+
+  #define FIREWALL_show_filter_s_length 6
+  #define FIREWALL_show_mangle_s_length 6
+  #define FIREWALL_show_nat_s_length    3
+
+  #define FIREWALL_show_bars_26_s_length 26
+  #define FIREWALL_show_bars_27_s_length 27
+  #define FIREWALL_show_bars_28_s_length 28
+
+  extern const f_string_static_t firewall_show_filter_s;
+  extern const f_string_static_t firewall_show_mangle_s;
+  extern const f_string_static_t firewall_show_nat_s;
+
+  extern const f_string_static_t firewall_show_bars_26_s;
+  extern const f_string_static_t firewall_show_bars_27_s;
+  extern const f_string_static_t firewall_show_bars_28_s;
+#endif // _di_firewall_show_s_
 
 #ifdef __cplusplus
 } // extern "C"
 #endif
 
-#endif // _firewall_common_h
+#endif // _firewall_common_string_h
diff --git a/level_3/firewall/c/main/common/type.c b/level_3/firewall/c/main/common/type.c
new file mode 100644 (file)
index 0000000..21bea93
--- /dev/null
@@ -0,0 +1,48 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_data_delete_
+  void firewall_data_delete(firewall_data_t * const data) {
+
+    if (!data) return;
+
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &data->buffer.string, &data->buffer.used, &data->buffer.size);
+    f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &data->chain_ids.string, &data->chain_ids.used, &data->chain_ids.size);
+    f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &data->delimits.string, &data->delimits.used, &data->delimits.size);
+    f_memory_array_resize(0, sizeof(f_range_t), (void **) &data->chain_objects.string, &data->chain_objects.used, &data->chain_objects.size);
+    f_memory_array_resize(0, sizeof(f_range_t), (void **) &data->rule_objects.string, &data->rule_objects.used, &data->rule_objects.size);
+
+    f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &data->chain_contents.array, &data->chain_contents.used, &data->chain_contents.size, &f_rangess_delete_callback);
+    f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &data->rule_contents.array, &data->rule_contents.used, &data->rule_contents.size, &f_rangess_delete_callback);
+  }
+#endif // _di_firewall_data_delete_
+
+#ifndef _di_firewall_main_delete_
+  void firewall_main_delete(firewall_main_t * const main) {
+
+    if (!main) return;
+
+    fll_program_data_delete(&main->program);
+    firewall_setting_delete(&main->setting);
+    firewall_data_delete(&main->data);
+  }
+#endif // _di_firewall_main_delete_
+
+#ifndef _di_firewall_setting_delete_
+  f_status_t firewall_setting_delete(firewall_setting_t * const setting) {
+
+    if (!setting) return F_status_set_error(F_parameter);
+
+    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &setting->chains.array, &setting->chains.used, &setting->chains.size, &f_string_dynamics_delete_callback);
+    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &setting->devices.array, &setting->devices.used, &setting->devices.size, &f_string_dynamics_delete_callback);
+
+    return F_okay;
+  }
+#endif // _di_firewall_setting_delete_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/common/type.h b/level_3/firewall/c/main/common/type.h
new file mode 100644 (file)
index 0000000..ff541db
--- /dev/null
@@ -0,0 +1,187 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the common type structures.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_common_type_h
+#define _firewall_common_type_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A data uses for building and processing firewall rules.
+ *
+ * Properties:
+ *   - is:  Flags used to represent the state in the current set being processed.
+ *   - has: Flags used to represent if each at has a position.
+ *
+ *   - device: The device position.
+ *   - lock:   The lock position.
+ *   - main:   The main position.
+ *   - stop:   The stop position.
+ *   - range:  A range used during operation processing.
+ *
+ *   - buffer: The buffer used for during processing.
+ *
+ *   - chain_ids: The list of chain IDs.
+ *   - delimits: The delimits array used when loading FSS data.
+ *
+ *   - chain_objects:  The list of chain Objects.
+ *   - rule_objects:   The list of rule Objects.
+ *   - chain_contents: The list of chain Contents.
+ *   - rule_contents:  The list of rule Contents.
+ */
+#ifndef _di_firewall_data_t_
+  typedef struct {
+    uint8_t is;
+    uint8_t has;
+
+    f_number_unsigned_t device;
+    f_number_unsigned_t lock;
+    f_number_unsigned_t main;
+    f_number_unsigned_t stop;
+    f_range_t range;
+
+    f_number_unsigneds_t chain_ids;
+    f_number_unsigneds_t delimits;
+
+    f_string_dynamic_t buffer;
+
+    f_ranges_t chain_objects;
+    f_ranges_t rule_objects;
+    f_rangess_t chain_contents;
+    f_rangess_t rule_contents;
+  } firewall_data_t;
+
+  #define firewall_data_t_initialize \
+    { \
+      firewall_data_is_none_e, \
+      firewall_data_has_none_e, \
+      0, \
+      0, \
+      0, \
+      0, \
+      f_range_t_initialize, \
+      f_number_unsigneds_t_initialize, \
+      f_number_unsigneds_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_ranges_t_initialize, \
+      f_ranges_t_initialize, \
+      f_rangess_t_initialize, \
+      f_rangess_t_initialize, \
+    }
+#endif // _di_firewall_data_t_
+
+/**
+ * The firewall main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * Properties:
+ *   - flag: Flags passed to the main function.
+ *
+ *   - status_signal: A status used eclusively by the threaded signal handler.
+ *   - state:         The state information.
+ *
+ *   - chains:  An array of all chains. @todo probably should be moved into data.
+ *   - devices: An array of all devices. @todo probably should be moved into data.
+ */
+#ifndef _di_firewall_setting_t_
+  typedef struct {
+    uint16_t flag;
+
+    f_status_t status_signal;
+    f_state_t state;
+
+    f_string_dynamics_t chains;
+    f_string_dynamics_t devices;
+  } firewall_setting_t;
+
+  #define firewall_setting_t_initialize \
+    { \
+      firewall_main_flag_none_e, \
+      F_okay, \
+      f_state_t_initialize, \
+      f_string_dynamics_t_initialize, \
+      f_string_dynamics_t_initialize, \
+    }
+#endif // _di_firewall_setting_t_
+
+/**
+ * The main program data as a single structure.
+ *
+ * Properties:
+ *   - program: The main program data.
+ *   - setting: The settings data.
+ *   - data:    The firewall data.
+ */
+#ifndef _di_firewall_main_t_
+  typedef struct {
+    fll_program_data_t program;
+    firewall_setting_t setting;
+    firewall_data_t data;
+  } firewall_main_t;
+
+  #define firewall_main_t_initialize \
+    { \
+      fll_program_data_t_initialize, \
+      firewall_setting_t_initialize, \
+      firewall_data_t_initialize, \
+    }
+#endif // _di_firewall_main_t_
+
+/**
+ * Deallocate firewall data.
+ *
+ * @param data
+ *   The firewall data.
+ *
+ *   This does not alter main.setting.state.status.
+ */
+#ifndef _di_firewall_data_delete_
+  extern void firewall_data_delete(firewall_data_t * const data);
+#endif // _di_firewall_data_delete_
+
+/**
+ * Deallocate main program data.
+ *
+ * @param setting_make
+ *   The make setting data.
+ *
+ *   This does not alter main.setting.state.status.
+ */
+#ifndef _di_firewall_main_delete_
+  extern void firewall_main_delete(firewall_main_t * const main);
+#endif // _di_firewall_main_delete_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ *   The program main setting data.
+ *
+ *   This does not alter setting.state.status.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_firewall_setting_delete_
+  extern f_status_t firewall_setting_delete(firewall_setting_t * const setting);
+#endif // _di_firewall_setting_delete_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_common_type_h
diff --git a/level_3/firewall/c/main/firewall.c b/level_3/firewall/c/main/firewall.c
new file mode 100644 (file)
index 0000000..14fe05b
--- /dev/null
@@ -0,0 +1,65 @@
+#include "firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_main_
+  void firewall_main(firewall_main_t * const main) {
+
+    if (!main) return;
+
+    if (F_status_is_error(main->setting.state.status)) {
+      if ((main->setting.flag & firewall_main_flag_print_last_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+        fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+      }
+
+      return;
+    }
+
+    if ((main->setting.flag & firewall_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+      fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+    }
+
+    main->setting.state.status = F_okay;
+
+    if (main->setting.flag & firewall_main_flag_version_copyright_help_e) {
+      if (main->setting.flag & firewall_main_flag_help_e) {
+        firewall_print_message_help(&main->program.message);
+      }
+      else if (main->setting.flag & firewall_main_flag_version_e) {
+        fll_program_print_version(&main->program.message, firewall_program_version_s);
+      }
+      else if (main->setting.flag & firewall_main_flag_copyright_e) {
+        fll_program_print_copyright(&main->program.message);
+      }
+
+      if ((main->setting.flag & firewall_main_flag_print_last_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+        fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+      }
+
+      return;
+    }
+
+    if (main->setting.flag & firewall_main_flag_operation_e) {
+      firewall_operate(main);
+    }
+    else {
+      main->setting.state.status = F_status_set_error(F_parameter);
+
+      firewall_print_error_operation_specified_not(&main->program.error);
+    }
+
+    if ((main->setting.flag & firewall_main_flag_print_last_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+      fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+    }
+
+    if (F_status_is_error(main->setting.state.status) || main->setting.state.status == F_interrupt) return;
+
+    main->setting.state.status = F_okay;
+  }
+#endif // _di_firewall_main_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/firewall.h b/level_3/firewall/c/main/firewall.h
new file mode 100644 (file)
index 0000000..445b8c9
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * This is the program is intended to be used to manage iptables.
+ *
+ * This program utilizes the Featureless Linux Library.
+ */
+#ifndef _firewall_h
+#define _firewall_h
+
+// Libc includes.
+#include <unistd.h>
+
+// FLL-0 includes.
+#include <fll/level_0/type.h>
+#include <fll/level_0/status.h>
+#include <fll/level_0/memory.h>
+#include <fll/level_0/string.h>
+#include <fll/level_0/utf.h>
+#include <fll/level_0/color.h>
+#include <fll/level_0/compare.h>
+#include <fll/level_0/console.h>
+#include <fll/level_0/conversion.h>
+#include <fll/level_0/directory.h>
+#include <fll/level_0/fss.h>
+#include <fll/level_0/file.h>
+#include <fll/level_0/pipe.h>
+#include <fll/level_0/print.h>
+#include <fll/level_0/rip.h>
+#include <fll/level_0/signal.h>
+#include <fll/level_0/thread.h>
+
+// FLL-1 includes.
+#include <fll/level_1/conversion.h>
+#include <fll/level_1/fss.h>
+#include <fll/level_1/print.h>
+
+// FLL-2 includes.
+#include <fll/level_2/error.h>
+#include <fll/level_2/fss.h>
+#include <fll/level_2/print.h>
+#include <fll/level_2/program.h>
+
+// Firewall includes.
+#include <program/firewall/main/common/define.h>
+#include <program/firewall/main/common/enumeration.h>
+#include <program/firewall/main/common/print.h>
+#include <program/firewall/main/common/string.h>
+#include <program/firewall/main/common/type.h>
+#include <program/firewall/main/common.h>
+#include <program/firewall/main/print/data.h>
+#include <program/firewall/main/print/debug.h>
+#include <program/firewall/main/print/error.h>
+#include <program/firewall/main/print/message.h>
+#include <program/firewall/main/print/verbose.h>
+#include <program/firewall/main/print/warning.h>
+#include <program/firewall/main/operate/buffer.h>
+#include <program/firewall/main/operate/create.h>
+#include <program/firewall/main/operate/default.h>
+#include <program/firewall/main/operate/delete.h>
+#include <program/firewall/main/operate/load.h>
+#include <program/firewall/main/operate/process.h>
+#include <program/firewall/main/signal.h>
+#include <program/firewall/main/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Execute main program.
+ *
+ * @param main
+ *   The main program and setting data.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *
+ *     F_interrupt (with error bit) on interrupt signal received.
+ *
+ *     Errors (with error bit) from: f_file_stream_open()
+ *     Errors (with error bit) from: firewall_load_line()
+ *     Errors (with error bit) from: firewall_process()
+ *
+ * @see f_file_stream_open()
+ * @see firewall_load_line()
+ * @see firewall_process()
+ */
+#ifndef _di_firewall_main_
+  extern void firewall_main(firewall_main_t * const main);
+#endif // _di_firewall_main_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_h
similarity index 51%
rename from level_3/firewall/c/main.c
rename to level_3/firewall/c/main/main.c
index 75b514a..d14c13b 100644 (file)
@@ -16,6 +16,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
   data.program.warning.custom = (void *) &data;
 
   f_console_parameter_t parameters[] = firewall_console_parameter_t_initialize;
+
   data.program.parameters.array = parameters;
   data.program.parameters.used = firewall_parameter_total_d;
   data.program.environment = envp;
@@ -26,23 +27,47 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
 
   fll_program_standard_set_up(&data.program);
 
-  {
-    const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp);
+  f_file_umask_get(&data.program.umask);
 
-    firewall_setting_load(arguments, &data);
-  }
+  #ifdef _di_thread_support_
+    {
+      const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp);
 
-  firewall_main(&data);
+      firewall_setting_load(arguments, &data);
+    }
 
-  firewall_setting_unload(&data);
+    firewall_main(&data);
+  #else
+    {
+      f_thread_id_t id_signal;
 
-  fll_program_data_delete(&data.program);
+      memset(&id_signal, 0, sizeof(f_thread_id_t));
 
-  fll_program_standard_set_down(&data.program);
+      data.setting.state.status = f_thread_create(0, &id_signal, &firewall_thread_signal, (void *) &data);
 
-  if (status == F_child) {
-    exit(data.child);
-  }
+      if (F_status_is_error(data.setting.state.status)) {
+        firewall_print_error(&data.program.error, macro_firewall_f(f_thread_create));
+      }
+      else {
+        {
+          const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp);
+
+          firewall_setting_load(arguments, &data);
+        }
+
+        if (!firewall_signal_check(&data)) {
+          firewall_main(&data);
+        }
+
+        f_thread_cancel(id_signal);
+        f_thread_join(id_signal, 0);
+      }
+    }
+  #endif // _di_thread_support_
+
+  firewall_main_delete(&data);
+
+  fll_program_standard_set_down(&data.program);
 
-  return F_status_is_error(data.setting.state.status) ? 1 : 0;
+  return (F_status_is_error(data.setting.state.status) || data.setting.state.status == F_false) ? 1 : 0;
 }
similarity index 97%
rename from level_3/firewall/c/main.h
rename to level_3/firewall/c/main/main.h
index 33c6a56..02816c1 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * FLL - Level 3
  *
- * Project: FSS Write
+ * Project: Firewall
  * API Version: 0.7
  * Licenses: lgpl-2.1-or-later
  *
diff --git a/level_3/firewall/c/main/operate.c b/level_3/firewall/c/main/operate.c
new file mode 100644 (file)
index 0000000..e1303fd
--- /dev/null
@@ -0,0 +1,466 @@
+#include "firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_operate_
+  void firewall_operate(firewall_main_t * const main) {
+
+    if (!main) return;
+
+    main->data.is = firewall_data_is_global_e;
+
+    if (main->setting.flag & firewall_main_flag_operation_show_e) {
+      int return_code = 0;
+
+      f_string_statics_t parameters = f_string_statics_t_initialize;
+      parameters.used = 6;
+
+      f_string_static_t show_nats[] = {
+        firewall_show_parameter_exact_s,
+        firewall_show_parameter_verbose_s,
+        firewall_show_parameter_table_s,
+        firewall_show_nat_s,
+        firewall_show_parameter_numeric_s,
+        firewall_show_parameter_list_s,
+      };
+
+      f_string_static_t show_mangles[] = {
+        firewall_show_parameter_exact_s,
+        firewall_show_parameter_verbose_s,
+        firewall_show_parameter_table_s,
+        firewall_show_mangle_s,
+        firewall_show_parameter_numeric_s,
+        firewall_show_parameter_list_s,
+      };
+
+      f_string_static_t show_filters[] = {
+        firewall_show_parameter_exact_s,
+        firewall_show_parameter_verbose_s,
+        firewall_show_parameter_numeric_s,
+        firewall_show_parameter_list_s,
+      };
+
+      const f_string_static_t show_arrays[][] = {
+        show_nats,
+        show_mangles,
+        show_filters,
+      };
+
+      const f_number_unsigned_t show_lengths[] = {
+        6,
+        6,
+        4,
+      };
+
+      const f_string_static_t show_lefts[] = {
+        firewall_show_bars_27_s,
+        firewall_show_bars_26_s,
+        firewall_show_bars_26_s,
+      };
+
+      const f_string_static_t show_headers[] = {
+        firewall_show_nat_s,
+        firewall_show_mangle_s,
+        firewall_show_filter_s,
+      };
+
+      const f_string_static_t show_rights[] = {
+        firewall_show_bars_28_s,
+        firewall_show_bars_26_s,
+        firewall_show_bars_26_s,
+      };
+
+      const uint16_t show_flags[] = {
+        firewall_main_flag_operation_show_nat_e,
+        firewall_main_flag_operation_show_mangle_e,
+        firewall_main_flag_operation_show_filter_e,
+      };
+
+      for (uint8_t i = 0; i < 3; ++i) {
+
+        if (!show_flags[i]) continue;
+
+        parameters.array = show_arrays[i];
+        parameters.used = show_lengths[i];
+
+        firewall_print_message_show_header(&main->output, show_lefts[i], show_headers[i], show_rights[i]);
+
+        main->setting.status = fll_execute_program(firewall_tool_iptables_s, parameters, 0, 0, (void *) &return_code);
+
+        if (status == F_child) {
+          main->child = return_code;
+
+          return;
+        }
+
+        fll_print_dynamic_raw(f_string_eol_s, main->output.to);
+        f_file_stream_flush(main->output.to);
+
+        if (F_status_is_error(main->setting.status)) {
+          firewall_print_error(&main->error
+          firewall_print_error_operation(&main->error, firewall_tool_iptables_s, parameters);
+
+          return;
+        }
+      } // for
+
+      return;
+    }
+
+    main->setting.state.status = f_directory_list(firewall_network_devices_s, 0, alphasort, &main->data.devices);
+
+    if (F_status_is_error(main->setting.state.status)) {
+      if (F_status_set_fine(main->setting.state.status) == F_data_not) {
+        firewall_print_error_network_device_none(&main->program.error);
+      }
+      else if (F_status_set_fine(main->setting.state.status) == F_failure) {
+        firewall_print_error_directory_read(&main->program.error, firewall_network_devices_s);
+      }
+      else {
+        firewall_print_error(&main->program.error, macro_firewall_f(f_console_parameter_process));
+      }
+
+      return;
+    }
+
+    f_number_unsigned_t i = 0;
+    f_string_static_t buffer = f_string_static_t_initialize;
+
+    // Remove "lo" (loopback) from the device listing.
+    for (; i < data.devices.used; ++i) {
+
+      if (f_compare_dynamic(firewall_device_loop_s, data.devices.array[i]) == F_equal_to) {
+        buffer = data.devices.array[i];
+
+        for (--data.devices.used; i < data.devices.used; ++i) {
+          data.devices.array[i] = data.devices.array[i + 1];
+        } // for
+
+        data.devices.array[data.devices.used] = buffer;
+      }
+    } // for
+
+    if (main->setting.flag & firewall_main_flag_operation_stop_restart_lock_e) {
+      buffer.used = firewall_network_path_s.used + firewall_file_other_s.used;
+
+      f_char_t path_file_other[buffer.used + 1];
+      buffer.string = path_file_other;
+      buffer[buffer.used] = 0;
+
+      memcpy(path_file_other, firewall_network_path_s.string, sizeof(f_char_t) * firewall_network_path_s.used);
+      memcpy(path_file_other + firewall_network_path_s.used, firewall_file_other_s.string, sizeof(f_char_t) * firewall_file_other_s.used);
+
+      firewall_operate_buffer_rules(&main, buffer, F_false);
+      if (F_status_is_error(main->setting.state.status) || main->setting.state.status == F_child) return;
+
+      for (i = 0; i < main->data.chain_objects.used; ++i) {
+
+        if (!(main->data.has & firewall_data_has_stop_e) && f_compare_dynamic_partial_string(firewall_group_stop_s.string, main->data.buffer, firewall_group_stop_s.used, main->data.chain_objects.array[i]) == F_equal_to) {
+          main->data.stop = i;
+          main->data.has |= firewall_data_has_stop_e;
+        }
+        else if (!(main->data.has & firewall_data_has_lock_e) && f_compare_dynamic_partial_string(firewall_group_lock_s.string, main->data.buffer, firewall_group_lock_s.used, main->data.chain_objects.array[i]) == F_equal_to) {
+          main->data.lock = i;
+          main->data.has |= firewall_data_has_lock_e;
+        }
+      } // for
+
+      if (main->setting.flag & firewall_main_flag_operation_lock_e) {
+        if (main->data.has & firewall_data_has_lock_e) {
+          firewall_operate_delete_chains(main);
+
+          if (F_status_is_error_not(main->setting.state.status) && main->setting.state.status != F_child) {
+            firewall_operate_default_lock(main);
+          }
+
+          if (F_status_is_error(main->setting.state.status) || main->setting.state.status == F_child) return;
+
+          //main->data.chain = main->data.lock; // @fixme
+          main->data.is = firewall_data_is_lock_e;
+          main->data.range.start = local.chain_contents.array[main->data.lock].array[0].start;
+          main->data.range.stop = local.chain_contents.array[main->data.lock].array[0].stop;
+
+          firewall_operate_load_rules(main);
+          firewall_operate_process_rules(main);
+        }
+        else {
+          main->setting.state.status = F_status_set_error(F_data);
+
+          firewall_print_error_operation_files_missing(&main->error, firewall_operation_lock_s, path_file_other);
+        }
+
+        return;
+      }
+
+      if (main->data.has & firewall_main_flag_operation_stop_restart_e) {
+        if (main->data.has & firewall_data_has_stop_e) {
+          firewall_operate_delete_chains(main);
+
+          if (F_status_is_error_not(main->setting.status) && main->setting.status != F_child) {
+            firewall_operate_default_lock(main);
+          }
+
+          if (F_status_is_error(status) || status == F_child) return;
+
+          local.is_global = F_true;
+          local.is_main = F_false;
+          local.is_stop = F_true;
+          local.is_lock = F_false;
+          local.chain = main->data.stop;
+
+          main->data.range.start = local.chain_contents.array[main->data.stop].array[0].start;
+          main->data.range.stop = local.chain_contents.array[main->data.stop].array[0].stop;
+
+          firewall_operate_load_rules(&main);
+          if (F_status_is_error(main->setting.state.status) || (main->data.has & firewall_main_flag_operation_stop_e) || main->setting.state.status == F_child) return;
+        }
+        else {
+          main->setting.state.status = F_status_set_error(F_data);
+
+          firewall_print_error_operation_files_missing(&main->error, firewall_operation_stop_s, path_file_other);
+
+          return;
+        }
+      }
+    }
+
+    /*
+    if (main->setting.flag & firewall_main_flag_operation_start_restart_e) {
+      f_string_static_t path_file_first = f_string_static_t_initialize;
+      path_file_first.used = firewall_network_path_s.used + firewall_file_first_s.used;
+
+      f_char_t path_file_first_string[path_file_first.used + 1];
+      path_file_first.string = path_file_first_string;
+      path_file_first_string[path_file_first.used] = 0;
+
+      memcpy(path_file_first_string, firewall_network_path_s.string, sizeof(f_char_t) * firewall_network_path_s.used);
+      memcpy(path_file_first_string + firewall_network_path_s.used, firewall_file_first_s.string, sizeof(f_char_t) * firewall_file_first_s.used);
+
+      status = firewall_operate_buffer_rules(&data, path_file_first, F_false, &local);
+
+      if (F_status_is_error(status) || status == F_child) {
+        firewall_delete_local_data(&local);
+        firewall_data_delete(&data);
+
+        return status;
+      }
+
+      if (command == firewall_parameter_command_start_e) {
+        status = firewall_operate_delete_chains(&data);
+
+        if (F_status_is_error_not(status) && status != F_child) {
+          status = firewall_operate_default_lock(&data);
+        }
+
+        if (F_status_is_error(status) || status == F_child) {
+          firewall_delete_local_data(&local);
+          firewall_data_delete(&data);
+
+          return status;
+        }
+      }
+
+      status = firewall_operate_create_custom_chains(&data, &reserved, &local);
+
+      if (F_status_is_error(status) || status == F_child) {
+        firewall_delete_local_data(&local);
+        firewall_data_delete(&data);
+
+        return status;
+      }
+
+      i = 0;
+      local.is_global = F_true;
+      local.is_stop = F_false;
+      local.is_lock = F_false;
+
+      while (i < local.chain_contents.used) {
+
+        input.start = local.chain_contents.array[i].array[0].start;
+        input.stop = local.chain_contents.array[i].array[0].stop;
+
+        local.is_main = reserved.has_main && i == main->data.main ? F_true : F_false;
+        local.chain = i;
+
+        status = firewall_operate_load_rules(&data, &input, &local);
+
+        if (F_status_is_error(status) || command == firewall_parameter_command_stop_e || status == F_child) {
+          firewall_delete_local_data(&local);
+          firewall_data_delete(&data);
+
+          return status;
+        }
+
+        ++i;
+      } // while
+
+      firewall_delete_local_data(&local);
+
+      {
+        f_string_dynamic_t path_file = f_string_dynamic_t_initialize;
+        f_number_unsigned_t j = 0;
+
+        for (i = 0; i < data.devices.used; ++i) {
+
+          path_file.used = 0;
+          local.device = i;
+
+          status = f_memory_array_increase_by(firewall_network_path_s.used + data.devices.array[i].used + firewall_file_suffix_s.used + 1, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+
+          if (F_status_is_error_not(status)) {
+            status = f_string_dynamic_append(firewall_network_path_s, &path_file);
+          }
+
+          if (F_status_is_error_not(status)) {
+            status = f_string_dynamic_append(data.devices.array[i], &path_file);
+          }
+
+          if (F_status_is_error_not(status)) {
+            status = f_string_dynamic_append(firewall_file_suffix_s, &path_file);
+          }
+
+          if (F_status_is_error(status)) {
+            firewall_print_error_on_allocation_failure(main->error);
+
+            firewall_delete_local_data(&local);
+            firewall_data_delete(&data);
+
+            return status;
+          }
+
+          status = firewall_operate_buffer_rules(&data, path_file, F_true, &local);
+
+          if (status == F_child) {
+            firewall_delete_local_data(&local);
+            firewall_data_delete(&data);
+
+            f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+
+            return status;
+          }
+
+          if (F_status_is_error(status)) {
+            status = F_status_set_fine(status);
+
+            firewall_delete_local_data(&local);
+
+            if (status == F_file_found_not || status == F_file_open || status == F_file_descriptor || status == F_fss_found_object_content_not) {
+              status = F_status_set_error(status);
+
+              continue;
+            }
+
+            f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+            firewall_data_delete(&data);
+
+            return F_status_set_error(status);
+          }
+
+          status = firewall_operate_create_custom_chains(&data, &reserved, &local);
+
+          if (F_status_is_error(status) || status == F_child) {
+            firewall_delete_local_data(&local);
+            firewall_data_delete(&data);
+
+            return status;
+          }
+
+          local.is_global = F_false;
+          local.is_stop = F_false;
+          local.is_lock = F_false;
+
+          for (j = 0; j < local.chain_contents.used; ++j) {
+
+            input.start = local.chain_contents.array[j].array[0].start;
+            input.stop = local.chain_contents.array[j].array[0].stop;
+
+            local.is_main = reserved.has_main && j == main->data.main ? F_true : F_false;
+            local.chain = j;
+
+            status = firewall_operate_load_rules(&data, &input, &local);
+
+            if (F_status_is_error(status) || command == firewall_parameter_command_stop_e || status == F_child) {
+              f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+
+              firewall_delete_local_data(&local);
+              firewall_data_delete(&data);
+
+              return status;
+            }
+          } // for
+
+          firewall_delete_local_data(&local);
+        } // for
+
+        path_file.used = 0;
+
+        status = f_string_dynamic_append(firewall_network_path_s, &path_file);
+
+        if (F_status_is_error_not(status)) {
+          status = f_string_dynamic_append(firewall_file_last_s, &path_file);
+        }
+
+        if (F_status_is_error_not(status)) {
+          status = firewall_operate_buffer_rules(&data, path_file, F_false, &local);
+        }
+
+        if (F_status_is_error(status) || status == F_child) {
+          f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+
+          firewall_delete_local_data(&local);
+          firewall_data_delete(&data);
+
+          return status;
+        }
+
+        status = firewall_operate_create_custom_chains(&data, &reserved, &local);
+
+        if (F_status_is_error(status) || status == F_child) {
+          f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+
+          firewall_delete_local_data(&local);
+          firewall_data_delete(&data);
+
+          return status;
+        }
+
+        i = 0;
+
+        local.is_global = F_true;
+        local.is_stop = F_false;
+        local.is_lock = F_false;
+
+        while (i < local.chain_contents.used) {
+
+          input.start = local.chain_contents.array[i].array[0].start;
+          input.stop = local.chain_contents.array[i].array[0].stop;
+
+          local.is_main = reserved.has_main && i == main->data.main ? F_true : F_false;
+          local.chain = i;
+
+          status = firewall_operate_load_rules(&data, &input, &local);
+
+          if (F_status_is_error(status) || command == firewall_parameter_command_stop_e || status == F_child) {
+            f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+
+            firewall_delete_local_data(&local);
+            firewall_data_delete(&data);
+
+            return status;
+          }
+
+          ++i;
+        } // while
+
+        f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+      }
+    }
+    */
+  }
+#endif // _di_firewall_operate_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/operate.h b/level_3/firewall/c/main/operate.h
new file mode 100644 (file)
index 0000000..ea54ede
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides operate functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_operate_h
+#define _firewall_operate_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the firewall operation.
+ *
+ * @param main
+ *   The main program and setting data.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *
+ *     F_interrupt (with error bit) on interrupt signal received.
+ *
+ *     Errors (with error bit) from: ()
+ *
+ * @see ()
+ */
+#ifndef _di_firewall_operate_
+  extern void firewall_operate(firewall_main_t * const main);
+#endif // _di_firewall_operate_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_operate_h
diff --git a/level_3/firewall/c/main/operate/buffer.c b/level_3/firewall/c/main/operate/buffer.c
new file mode 100644 (file)
index 0000000..2544b42
--- /dev/null
@@ -0,0 +1,125 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_operate_buffer_rules_
+  f_status_t firewall_operate_buffer_rules(firewall_main_t * const main, const f_string_static_t filename, const bool optional) {
+
+    if (!main) return F_status_set_error(F_parameter);
+
+    f_file_t file = f_file_t_initialize;
+
+    f_status_t status = f_file_open(filename, 0, &file);
+
+    if (F_status_is_error(status)) {
+      if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
+        if (optional) {
+          if (F_status_set_fine(status) == F_parameter) {
+            firewall_print_error_on_invalid_parameter(data->main->error, "f_file_open");
+          }
+          else if (F_status_set_fine(status) != F_file_found_not && F_status_set_fine(status) != F_file_open && F_status_set_fine(status) != F_file_descriptor) {
+            firewall_print_error_on_unhandled(data->main->error, "f_file_open", F_status_set_fine(status));
+          }
+        } else {
+          if (F_status_set_fine(status) == F_parameter) {
+            firewall_print_error_on_invalid_parameter(data->main->error, "f_file_open");
+          }
+          else if (F_status_set_fine(status) == F_file_found_not) {
+            fll_print_format("%r%[%QUnable to find the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
+          }
+          else if (F_status_set_fine(status) == F_file_open) {
+            fll_print_format("%r%[%QUnable to open the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
+          }
+          else if (F_status_set_fine(status) == F_file_descriptor) {
+            fll_print_format("%r%[%QFile descriptor error while trying to open the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
+          }
+          else {
+            firewall_print_error_on_unhandled(data->main->error, "f_file_open", F_status_set_fine(status));
+          }
+        }
+      }
+
+      return status;
+    }
+
+    status = f_file_read(file, &local->buffer);
+
+    f_file_stream_flush(file);
+    f_file_stream_close(&file);
+
+    if (F_status_is_error(status)) {
+      if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
+        if (F_status_set_fine(status) == F_parameter) {
+          firewall_print_error_on_invalid_parameter(data->main->error, "f_file_read");
+        }
+        else if (F_status_set_fine(status) == F_number_overflow) {
+          fll_print_format("%r%[%QInteger overflow while trying to buffer the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
+        }
+        else if (F_status_set_fine(status) == F_file_closed) {
+          fll_print_format("%r%[%QThe file '%Q' is no longer open.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
+        }
+        else if (F_status_set_fine(status) == F_file_seek) {
+          fll_print_format("%r%[%QA seek error occurred while accessing the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
+        }
+        else if (F_status_set_fine(status) == F_file_read) {
+          fll_print_format("%r%[%QA read error occurred while accessing the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
+        }
+        else if (F_status_set_fine(status) == F_memory_not) {
+          firewall_print_error_on_allocation_failure(data->main->error);
+        }
+        else {
+          firewall_print_error_on_unhandled(data->main->error, "f_file_read", F_status_set_fine(status));
+        }
+      }
+
+      return status;
+    }
+
+    f_number_unsigneds_t delimits = f_number_unsigneds_t_initialize;
+    f_range_t comments = f_range_t_initialize;
+    f_state_t state = f_state_t_initialize;
+
+    {
+      f_range_t input = macro_f_range_t_initialize_2(local->buffer.used);
+
+      status = fll_fss_basic_list_read(local->buffer, state, &input, &local->chain_objects, &local->chain_contents, &delimits, 0, &comments);
+    }
+
+    if (F_status_is_error(status)) {
+      status = F_status_set_fine(status);
+
+      if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
+        if (status == F_parameter) {
+          firewall_print_error_on_invalid_parameter_for_file(data->main->error, "fll_fss_basic_list_read", filename);
+        }
+        else if (status == F_data_not_eos || status == F_data_not || status == F_data_not_stop) {
+          fll_print_format("%r%[%QNo relevant main was found within the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
+        }
+        else if (status == F_memory_not) {
+          firewall_print_error_on_allocation_failure(data->main->error);
+        }
+        else {
+          firewall_print_error_on_unhandled_for_file(data->main->error, "fll_fss_basic_read", status, filename);
+        }
+      }
+    }
+    else {
+      status = f_fss_apply_delimit(state, delimits, &local->buffer);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data->main->error, F_status_set_fine(status), "f_fss_apply_delimit", fll_error_file_flag_fallback_e);
+      }
+    }
+
+    f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
+    macro_f_range_t_delete_simple(comments);
+
+    return status;
+  }
+#endif // _di_firewall_operate_buffer_rules_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/operate/buffer.h b/level_3/firewall/c/main/operate/buffer.h
new file mode 100644 (file)
index 0000000..ec4e9af
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the buffer functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_operate_buffer_h
+#define _firewall_operate_buffer_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Buffer firewall rules.
+ *
+ * @param data
+ *   The program data.
+ * @param filename
+ *   File name to read the rules from.
+ * @param optional
+ *   TRUE if this files is optional.
+ *   FALSE otherwise (more are errors returned when not optional).
+ * @param local
+ *   Local firewall settings.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_child on child process exiting.
+ *
+ *   Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_firewall_operate_buffer_rules_
+  extern f_status_t firewall_operate_buffer_rules(firewall_main_t * const main, const f_string_static_t filename, const bool optional);
+#endif // _di_firewall_operate_buffer_rules_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_operate_buffer_h
diff --git a/level_3/firewall/c/main/operate/create.c b/level_3/firewall/c/main/operate/create.c
new file mode 100644 (file)
index 0000000..0624b22
--- /dev/null
@@ -0,0 +1,203 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_operate_create_custom_chains_
+  f_status_t firewall_operate_create_custom_chains(firewall_main_t * const main) {
+
+    if (!main) return F_status_set_error(F_parameter);
+
+    f_status_t status = F_okay;
+
+    uint8_t tool = firewall_program_iptables_e;
+    bool new_chain = F_false;
+    bool create_chain = F_false;
+    int return_code = 0;
+
+    f_number_unsigned_t i = 0;
+    f_number_unsigned_t j = 0;
+
+    f_number_unsigned_t length = 0;
+    f_string_dynamics_t arguments = f_string_dynamics_t_initialize;
+
+    local->chain_ids.used = local->chain_objects.used;
+
+    status = f_memory_arrays_resize(2, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+    if (F_status_is_error(status)) return status;
+
+    status = f_memory_array_increase_by(local->chain_objects.used, sizeof(f_number_unsigned_t), (void **) &local->chain_ids.array, &local->chain_ids.used, &local->chain_ids.size);
+    if (F_status_is_error(status)) return status;
+
+    memset(local->chain_ids.array, 0, sizeof(f_number_unsigned_t) * local->chain_ids.used);
+
+    status = f_string_dynamic_append(firewall_chain_create_command_s, &arguments.array[0]);
+
+    if (F_status_is_error_not(status)) {
+      status = f_memory_array_increase(F_memory_default_allocation_small_d, sizeof(f_char_t), (void **) &arguments.array[1].string, &arguments.array[1].used, &arguments.array[1].size);
+    }
+    else {
+      f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+
+      return status;
+    }
+
+    arguments.used = 2;
+
+    reserved->has_lock = F_false;
+    reserved->has_stop = F_false;
+    reserved->has_main = F_false;
+
+    for (; i < local->chain_objects.used; ++i) {
+
+      new_chain = F_true;
+      j = 0;
+
+      if (!((++data->main->signal_check) % firewall_signal_check_d)) {
+        if (firewall_signal_received(data)) break;
+      }
+
+      // Skip globally reserved chain name: main.
+      if (f_compare_dynamic_partial_string(firewall_group_main_s.string, local->buffer, firewall_group_main_s.used, local->chain_objects.array[i]) == F_equal_to) {
+        new_chain = F_false;
+        reserved->has_main = F_true;
+        reserved->main_at = i;
+      }
+
+      // Skip globally reserved chain name: stop.
+      if (f_compare_dynamic_partial_string(firewall_group_stop_s.string, local->buffer, firewall_group_stop_s.used, local->chain_objects.array[i]) == F_equal_to) {
+        new_chain = F_false;
+        reserved->has_stop = F_true;
+        reserved->stop_at = i;
+      }
+
+      // Skip globally reserved chain name: lock.
+      if (f_compare_dynamic_partial_string(firewall_group_lock_s.string, local->buffer, firewall_group_lock_s.used, local->chain_objects.array[i]) == F_equal_to) {
+        new_chain = F_false;
+        reserved->has_lock = F_true;
+        reserved->lock_at = i;
+      }
+
+      // Skip globally reserved chain name: none.
+      if (f_compare_dynamic_partial_string(firewall_chain_none_s.string, local->buffer, firewall_chain_none_s.used, local->chain_objects.array[i]) == F_equal_to) {
+        new_chain = F_false;
+      }
+
+      if (new_chain) {
+        for (; j < data->chains.used; ++j) {
+
+          if (f_compare_dynamic_partial_string(data->chains.array[j].string, local->buffer, data->chains.array[j].used, local->chain_objects.array[i]) == F_equal_to) {
+            new_chain = F_false;
+            local->chain_ids.array[i] = j;
+
+            break;
+          }
+        } // for
+      }
+
+      if (new_chain) {
+        status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &data->chains.array, &data->chains.used, &data->chains.size);
+        if (F_status_is_error(status)) break;
+
+        create_chain = F_true;
+        length = (local->chain_objects.array[i].stop - local->chain_objects.array[i].start) + 1;
+
+        arguments.array[1].used = 0;
+
+        status = f_memory_array_increase_by(length + 1, sizeof(f_char_t), (void **) &arguments.array[1].string, &arguments.array[1].used, &arguments.array[1].size);
+        if (F_status_is_error(status)) break;
+
+        status = f_memory_array_increase_by(length + 1, sizeof(f_char_t), (void **) &data->chains.array[data->chains.used].string, &data->chains.array[data->chains.used].used, &data->chains.array[data->chains.used].size);
+        if (F_status_is_error(status)) break;
+
+        data->chains.array[data->chains.used].used = 0;
+        local->chain_ids.array[i] = data->chains.used;
+
+        // Copy the string character by character, ignoring placeholders.
+        for (j = local->chain_objects.array[i].start; j <= local->chain_objects.array[i].stop; ++j) {
+
+          if (local->buffer.string[j] == f_fss_placeholder_s.string[0]) continue;
+
+          data->chains.array[data->chains.used].string[data->chains.array[data->chains.used].used++] = local->buffer.string[j];
+          arguments.array[1].string[arguments.array[1].used++] = local->buffer.string[j];
+        } // for
+
+        arguments.array[1].string[arguments.array[1].used] = 0;
+        data->chains.array[data->chains.used].string[data->chains.array[data->chains.used].used] = 0;
+
+        if (f_compare_dynamic(arguments.array[1], firewall_chain_forward_s) == F_equal_to) {
+          create_chain = F_false;
+        }
+        else if (f_compare_dynamic(arguments.array[1], firewall_chain_input_s) == F_equal_to) {
+          create_chain = F_false;
+        }
+        else if (f_compare_dynamic(arguments.array[1], firewall_chain_output_s) == F_equal_to) {
+          create_chain = F_false;
+        }
+        else if (f_compare_dynamic(arguments.array[1], firewall_chain_postrouting_s) == F_equal_to) {
+          create_chain = F_false;
+        }
+        else if (f_compare_dynamic(arguments.array[1], firewall_chain_prerouting_s) == F_equal_to) {
+          create_chain = F_false;
+        }
+
+        if (create_chain) {
+          firewall_print_debug_tool(data->main->warning, firewall_tool_iptables_s, arguments);
+
+          tool = firewall_program_iptables_e;
+          status = fll_execute_program(firewall_tool_iptables_s, arguments, 0, 0, (void *) &return_code);
+
+          if (status == F_child) {
+            data->main->child = return_code;
+
+            break;
+          }
+
+          if (F_status_is_error_not(status)) {
+            if (firewall_signal_received(data)) {
+              status = F_status_set_error(F_interrupt);
+
+              break;
+            }
+
+            firewall_print_debug_tool(data->main->warning, firewall_tool_ip6tables_s, arguments);
+
+            tool = firewall_program_ip6tables_e;
+            status = fll_execute_program(firewall_tool_ip6tables_s, arguments, 0, 0, (void *) &return_code);
+
+            if (status == F_child) {
+              data->main->child = return_code;
+
+              break;
+            }
+          }
+
+          if (F_status_is_error(status)) {
+            if (F_status_set_fine(status) == F_failure) {
+              firewall_print_error_operation(data->main->error, tool == firewall_program_iptables_e ? firewall_tool_iptables_s : firewall_tool_ip6tables_s, arguments);
+            }
+            else if (F_status_set_fine(status) == F_parameter) {
+              firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
+            }
+            else {
+              firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
+            }
+
+            break;
+          }
+        }
+
+        ++data->chains.used;
+      }
+    } // for
+
+    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+
+    return status;
+  }
+#endif // _di_firewall_operate_create_custom_chains_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/operate/create.h b/level_3/firewall/c/main/operate/create.h
new file mode 100644 (file)
index 0000000..d3b8455
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the create functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_operate_create_h
+#define _firewall_operate_create_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Create custom chains.
+ *
+ * @param data
+ *   The program data.
+ * @param reserved
+ *   firewall chains.
+ * @param local
+ *   Local firewall settings.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_child on child process exiting.
+ *
+ *   F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal.
+ *   F_parameter (with error bit) on invalid parameter passed.
+ *
+ *   Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_firewall_operate_create_custom_chains_
+  extern f_status_t firewall_operate_create_custom_chains(firewall_main_t * const main);
+#endif / _di_firewall_operate_create_custom_chains_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_operate_create_h
diff --git a/level_3/firewall/c/main/operate/default.c b/level_3/firewall/c/main/operate/default.c
new file mode 100644 (file)
index 0000000..5b84d10
--- /dev/null
@@ -0,0 +1,76 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_operate_default_lock_
+  f_status_t firewall_operate_default_lock(firewall_data_t * const data) {
+
+    if (!data) return F_status_set_error(F_parameter);
+
+    const f_string_static_t chains[3] = { firewall_chain_input_s, firewall_chain_output_s, firewall_chain_forward_s };
+    const f_string_static_t tools[2] = { firewall_tool_iptables_s, firewall_tool_ip6tables_s };
+
+    f_status_t status = F_okay;
+
+    int return_code = 0;
+
+    f_string_statics_t arguments = f_string_statics_t_initialize;
+    arguments.used = 3;
+
+    f_string_static_t argument_array[arguments.used];
+    arguments.array = argument_array;
+    arguments.array[0] = firewall_action_policy_command_s;
+    arguments.array[2] = firewall_chain_drop_s;
+
+    f_number_unsigned_t i = 0;
+    f_number_unsigned_t j = 0;
+
+    for (; i < 3; ++i) {
+
+      arguments.array[1] = chains[i];
+
+      for (j = 0; j < 2; ++j) {
+
+        firewall_print_debug_tool(data->main->warning, tools[j], arguments);
+
+        return_code = 0;
+
+        status = fll_execute_program(tools[j], arguments, 0, 0, (void *) &return_code);
+
+        if (status == F_child) {
+          data->main->child = return_code;
+
+          break;
+        }
+
+        if (firewall_signal_received(data)) {
+          status = F_status_set_error(F_interrupt);
+
+          break;
+        }
+
+        if (F_status_is_error(status)) {
+          if (F_status_set_fine(status) == F_failure) {
+            firewall_print_error_operation(data->main->error, tools[j], arguments);
+          }
+          else if (F_status_set_fine(status) == F_parameter) {
+            firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
+          }
+          else {
+            firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
+          }
+
+          break;
+        }
+      } // for
+    } // for
+
+    return status;
+  }
+#endif // _di_firewall_operate_default_lock_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/operate/default.h b/level_3/firewall/c/main/operate/default.h
new file mode 100644 (file)
index 0000000..5fb890e
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the default functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_operate_default_h
+#define _firewall_operate_default_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Lock the firewall.
+ *
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_child on child process exiting.
+ *
+ *   Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_firewall_operate_default_lock_
+  extern f_status_t firewall_operate_default_lock(firewall_main_t * const main);
+#endif // _di_firewall_operate_default_lock_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_operate_default_h
diff --git a/level_3/firewall/c/main/operate/delete.c b/level_3/firewall/c/main/operate/delete.c
new file mode 100644 (file)
index 0000000..95b72df
--- /dev/null
@@ -0,0 +1,105 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_operate_delete_chains_
+  f_status_t firewall_operate_delete_chains(firewall_main_t * const main) {
+
+    if (!data) return F_status_set_error(F_parameter);
+
+    const f_string_static_t tools[2] = { firewall_tool_iptables_s, firewall_tool_ip6tables_s };
+    f_status_t status = F_okay;
+
+    for (f_number_unsigned_t i = 0; i < 2; ++i) {
+
+      if (firewall_signal_received(data)) {
+        return F_status_set_error(F_interrupt);
+      }
+
+      f_string_statics_t arguments = f_string_statics_t_initialize;
+      arguments.used = 1;
+
+      f_string_static_t arguments_array[arguments.used];
+      arguments_array[0] = firewall_chain_flush_command_s;
+      arguments.array = arguments_array;
+
+      int return_code = 0;
+
+      firewall_print_debug_tool(data->main->warning, tools[i], arguments);
+
+      status = fll_execute_program(tools[i], arguments, 0, 0, (void *) &return_code);
+
+      if (status == F_child) {
+        data->main->child = return_code;
+
+        return status;
+      }
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_failure) {
+          firewall_print_error_operation(data->main->error, tools[i], arguments);
+        }
+        else if (F_status_set_fine(status) == F_parameter) {
+          firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
+        }
+        else {
+          firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
+        }
+
+        return status;
+      }
+    } // for
+
+    int return_code = 0;
+
+    f_string_statics_t arguments = f_string_statics_t_initialize;
+    arguments.used = 1;
+
+    f_string_static_t argument_array[arguments.used];
+    arguments.array = argument_array;
+    argument_array[0] = firewall_chain_delete_command_s;
+
+    for (f_number_unsigned_t i = 0; i < 2; ++i) {
+
+      firewall_print_debug_tool(data->main->warning, tools[i], arguments);
+
+      return_code = 0;
+
+      status = fll_execute_program(tools[i], arguments, 0, 0, (void *) &return_code);
+
+      if (status == F_child) {
+        data->main->child = return_code;
+
+        break;
+      }
+
+      if (firewall_signal_received(data)) {
+        status = F_status_set_error(F_interrupt);
+
+        break;
+      }
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_failure) {
+          firewall_print_error_operation(data->main->error, tools[i], arguments);
+        }
+        else if (F_status_set_fine(status) == F_parameter) {
+          firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
+        }
+        else {
+          firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
+        }
+
+        break;
+      }
+    } // for
+
+    return status;
+  }
+#endif // _di_firewall_operate_delete_chains_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/operate/delete.h b/level_3/firewall/c/main/operate/delete.h
new file mode 100644 (file)
index 0000000..2b0a8a1
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the delete functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_operate_delete_h
+#define _firewall_operate_delete_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Deallocate chains.
+ *
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_child on child process exiting.
+ *
+ *   F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal.
+ *   F_parameter (with error bit) on invalid parameter passed.
+ *
+ *   Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_firewall_operate_delete_chains_
+  extern f_status_t firewall_operate_delete_chains(firewall_main_t * const main);
+#endif // _di_firewall_operate_delete_chains_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_operate_delete_h
diff --git a/level_3/firewall/c/main/operate/load.c b/level_3/firewall/c/main/operate/load.c
new file mode 100644 (file)
index 0000000..9e558de
--- /dev/null
@@ -0,0 +1,39 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_operate_load_rules_
+  void firewall_operate_load_rules(firewall_main_t * const main) {
+
+    if (!main) return;
+
+    main->data.buffer.used = 0;
+    main->data.delimits.used = 0;
+    main->data.rule_objects.used = 0;
+    main->data.rule_contents.used = 0;
+
+    main->setting.state.status = fll_fss_extended_read(main->data.buffer, main->setting.state, main->data.range, &main->data.rule_objects, &main->data.rule_contents, 0, 0, &main->data.delimits, 0);
+
+    if (F_status_is_error(main->setting.state.status)) {
+      firewall_print_error(&main->program.error, macro_firewall_f(fll_fss_extended_read));
+
+      return;
+    }
+
+    main->setting.state.status = f_fss_apply_delimit(main->setting.state, main->data.delimits, &main->data.buffer);
+
+    if (F_status_is_error(main->setting.state.status)) {
+      firewall_print_error(&main->program.error, macro_firewall_f(f_fss_apply_delimit));
+
+      return;
+    }
+
+    main->setting.state.status = F_okay;
+  }
+#endif // _di_firewall_operate_load_rules_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/operate/load.h b/level_3/firewall/c/main/operate/load.h
new file mode 100644 (file)
index 0000000..e4b3632
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the load functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_operate_load_h
+#define _firewall_operate_load_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Process buffered rules.
+ *
+ * @param data
+ *   The program data.
+ * @param chain
+ *   The position representing the current chain being processed.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_child on child process exiting.
+ *
+ *   Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_firewall_operate_load_rules_
+  extern f_status_t firewall_operate_load_rules(firewall_main_t * const main);
+#endif // _di_firewall_operate_load_rules_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_operate_load_h
diff --git a/level_3/firewall/c/main/operate/process.c b/level_3/firewall/c/main/operate/process.c
new file mode 100644 (file)
index 0000000..d804c6a
--- /dev/null
@@ -0,0 +1,800 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_operate_process_rules_
+  void firewall_operate_process_rules(firewall_main_t * const main) {
+
+    if (!main || F_status_is_error(main->setting.state.status)) return;
+
+    firewall_operate_process_rules_perform(main);
+
+    if (F_status_is_error(main->setting.state.status)) {
+      if (F_status_set_fine(main->setting.state.status) != F_failure) {
+        firewall_print_error_unhandled(&main->error, macro_firewall_f(firewall_operate_process_rules_perform));
+      }
+    }
+    else {
+      main->setting.state.status = F_okay;
+    }
+  }
+#endif // _di_firewall_operate_process_rules_
+
+#ifndef _di_firewall_operate_process_rules_perform_
+  void firewall_operate_process_rules_perform(firewall_main_t * const main) {
+
+    if (!main) return;
+
+    bool invalid = F_false;
+    bool is_ip_list = F_false;
+
+    // Iptables command arguments
+    bool ip_list_direction = F_false; // false = source, true = destination.
+    bool use_protocol = F_false;
+    uint8_t tool = firewall_program_ip46tables_e;
+    uint8_t chain = firewall_chain_none_id_e;
+
+    int return_code = 0;
+
+    f_number_unsigned_t i = 0;
+    f_number_unsigned_t r = 0;
+    f_number_unsigned_t repeat = 2;
+    f_number_unsigned_t length = 0;
+
+    f_string_static_t current_tool = firewall_tool_iptables_s;
+
+    uint8_t direction = firewall_direction_none_id_e;
+    uint8_t action = firewall_action_append_id_e;
+
+    f_string_dynamic_t ip_list = f_string_dynamic_t_initialize;
+    f_string_dynamic_t device = f_string_dynamic_t_initialize;
+    f_string_dynamic_t protocol = f_string_dynamic_t_initialize;
+    f_string_dynamics_t arguments = f_string_dynamics_t_initialize;
+
+    if (!local->is_global) {
+      if (data->devices.array[local->device].used) {
+        device.used = 0;
+
+        status = f_string_dynamic_append(data->devices.array[local->device], &device);
+
+        if (F_status_is_error(status)) {
+          if (F_status_set_fine(status) == F_memory_not) {
+            firewall_print_error_on_allocation_failure(data->main->error);
+          }
+
+          return status;
+        }
+      }
+    }
+
+    // For custom chains, the chain command may not be specified.
+    if (!(local->is_main || local->is_stop || local->is_lock)) {
+      chain = firewall_chain_custom_id_e;
+    }
+
+    for (; F_status_is_error_not(status) && i < local->rule_objects.used; ++i) {
+
+      if (!((++data->main->signal_check) % firewall_signal_check_d)) {
+        if (firewall_signal_received(data)) {
+          f_memory_array_resize(0, sizeof(f_char_t), (void **) &ip_list.string, &ip_list.used, &ip_list.size);
+          f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
+          f_memory_array_resize(0, sizeof(f_char_t), (void **) &protocol.string, &protocol.used, &protocol.size);
+
+          f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+
+          return F_status_set_error(F_interrupt);
+        }
+
+        data->main->signal_check = 0;
+      }
+
+      length = (local->rule_objects.array[i].stop - local->rule_objects.array[i].start) + 1;
+      invalid = F_false;
+
+      is_ip_list = F_false;
+      ip_list_direction = F_false;
+
+      ip_list.used = 0;
+
+      // Process chain rule.
+      if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_chain_s, length) == F_equal_to) {
+        if (chain == firewall_chain_custom_id_e) {
+
+          // Custom chains can only apply to themselves, so silently ignore chain commands specified within a custom chain.
+          fll_print_format("%r%[%QAt line %ul, the chain option is meaningless inside of a custom chain.%]%r", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context, f_string_eol_s);
+
+          continue;
+        }
+
+        length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
+
+        if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
+          invalid = F_true;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_input_s, length) == F_equal_to) {
+          chain = firewall_chain_input_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_output_s, length) == F_equal_to) {
+          chain = firewall_chain_output_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_forward_s, length) == F_equal_to) {
+          chain = firewall_chain_forward_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_postrouting_s, length) == F_equal_to) {
+          chain = firewall_chain_postrouting_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_prerouting_s, length) == F_equal_to) {
+          chain = firewall_chain_prerouting_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_none_s, length) == F_equal_to) {
+          chain = firewall_chain_none_id_e;
+        }
+        else {
+          invalid = F_true;
+        }
+
+        if (!invalid) continue;
+      }
+
+      // Process direction rule
+      else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_direction_s, length) == F_equal_to) {
+        length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
+
+        if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
+          invalid = F_true;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_direction_input_s, length) == F_equal_to) {
+          direction = firewall_direction_input_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_direction_output_s, length) == F_equal_to) {
+          direction = firewall_direction_output_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_direction_none_s, length) == F_equal_to) {
+          direction = firewall_direction_none_id_e;
+        }
+        else {
+
+          // Direction must be specified, and no custom directions are allowed.
+          invalid = F_true;
+        }
+
+        if (!invalid) continue;
+      }
+
+      // Process device rule.
+      else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_device_s, length) == F_equal_to) {
+        length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
+
+        if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
+          invalid = F_true;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_device_all_s, length) == F_equal_to) {
+          f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
+
+          continue;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_device_this_s, length) == F_equal_to) {
+          if (data->devices.array[local->device].used) {
+            status = f_memory_array_increase_by(data->devices.array[local->device].used, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
+            if (F_status_is_error(status)) break;
+
+            memcpy(device.string, data->devices.array[local->device].string, sizeof(f_char_t) * data->devices.array[local->device].used);
+
+            device.used = data->devices.array[local->device].used;
+          }
+          else {
+            f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
+          }
+
+          continue;
+        }
+
+        if (!invalid) {
+          device.used = 0;
+
+          if (length) {
+            status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[0], &device);
+
+            if (F_status_is_error(status)) break;
+          }
+
+          continue;
+        }
+      }
+
+      // Process action rule.
+      else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_action_s, length) == F_equal_to) {
+        length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
+
+        if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
+          invalid = F_true;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_action_append_s, length) == F_equal_to) {
+          action = firewall_action_append_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_action_insert_s, length) == F_equal_to) {
+          action = firewall_action_insert_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_action_policy_s, length) == F_equal_to) {
+          action = firewall_action_policy_id_e;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_action_none_s, length) == F_equal_to) {
+          action = firewall_action_none_id_e;
+        }
+        else {
+          invalid = F_true;
+        }
+
+        if (!invalid) continue;
+      }
+
+      // Process ip_list rule.
+      else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_ip_list, length) == F_equal_to) {
+        length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
+        is_ip_list = F_true;
+
+        if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_ip_list_source_s, length) == F_equal_to) {
+          ip_list_direction = F_false;
+        }
+        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_ip_list_destination_s, length) == F_equal_to) {
+          ip_list_direction = F_true;
+        }
+        else {
+          invalid = F_true;
+        }
+      }
+      else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_protocol_s, length) == F_equal_to) {
+        length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
+
+        if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
+          invalid = F_true;
+        }
+        else {
+          if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_protocol_none_s, length) == F_equal_to) {
+            use_protocol = F_false;
+          }
+          else if (length) {
+            protocol.used = 0;
+
+            status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[0], &protocol);
+
+            if (F_status_is_error(status)) break;
+
+            use_protocol = F_true;
+          }
+          else {
+            use_protocol = F_false;
+          }
+
+          continue;
+        }
+      }
+
+      // Process tool rule.
+      else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_tool_s, length) == F_equal_to) {
+        length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
+
+        if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
+          invalid = F_true;
+        }
+        else {
+          if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_tool_iptables_s, length) == F_equal_to) {
+            tool = firewall_program_iptables_e;
+            current_tool = firewall_tool_iptables_s;
+            repeat = 1;
+          }
+          else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_tool_ip6tables_s, length) == F_equal_to) {
+            tool = firewall_program_ip6tables_e;
+            current_tool = firewall_tool_ip6tables_s;
+            repeat = 1;
+          }
+          else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_tool_ip46tables_s, length) == F_equal_to) {
+            tool = firewall_program_ip46tables_e;
+            current_tool = firewall_tool_iptables_s;
+            repeat = 2;
+          }
+          else {
+            invalid = F_true;
+          }
+
+          if (!invalid) continue;
+        }
+      }
+
+      // If the remaining rule does not match as firewall_rule_s, then it is an invalid rule.
+      else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_rule_s, length) == F_equal_to_not) {
+        if (length) {
+          f_file_stream_lock(data->main->warning.to);
+
+          fl_print_format("%r%[%QAt line %ul, the object '%]", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context, data->main->warning.notable);
+          fl_print_format(f_string_format_Q_range_single_s.string, data->main->warning.to, data->main->warning.notable, local->buffer, local->rule_objects.array[i], data->main->warning.notable);
+          fl_print_format("%[' is invalid.%]%r", data->main->warning.to, data->main->warning.context, data->main->warning.context, f_string_eol_s);
+
+          f_file_stream_unlock(data->main->warning.to);
+        }
+        else {
+          fll_print_format("%r%[%QAt line %ul, the object is missing.%]%r", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context, f_string_eol_s);
+        }
+
+        continue;
+      }
+
+      if (invalid) {
+        length = (local->rule_objects.array[i].stop - local->rule_objects.array[i].start) + 1;
+
+        if (length) {
+          f_file_stream_lock(data->main->warning.to);
+
+          fl_print_format("%r%[%QAt line %ul, the object '%]", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context);
+          fl_print_format(f_string_format_Q_range_single_s.string, data->main->warning.to, data->main->warning.notable, local->buffer, local->rule_objects.array[i], data->main->warning.notable);
+          fl_print_format("%[' has invalid content '%]", data->main->warning.to, data->main->warning.context, data->main->warning.context);
+          fl_print_format(f_string_format_Q_range_single_s.string, data->main->warning.to, data->main->warning.notable, local->buffer, local->rule_contents.array[i].array[0], data->main->warning.notable);
+          fl_print_format(f_string_format_sentence_end_quote_s.string, data->main->warning.to, data->main->warning.context, data->main->warning.context, f_string_eol_s);
+
+          f_file_stream_unlock(data->main->warning.to);
+        }
+        else {
+          fll_print_format("%r%[%QAt line %ul, the object has no content.%]%r", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context, f_string_eol_s);
+        }
+
+        continue;
+      }
+
+      for (r = repeat; F_status_is_error_not(status) && r; --r) {
+
+        arguments.used = 0;
+
+        // First add the program name.
+        status = f_memory_array_increase(F_memory_default_allocation_small_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+        if (F_status_is_error(status)) break;
+
+        if (tool == firewall_program_ip46tables_e) {
+          if (r == 2) {
+            current_tool = firewall_tool_iptables_s;
+          }
+          else {
+            current_tool = firewall_tool_ip6tables_s;
+          }
+        }
+
+        // Process the action when a non-none chain is specified.
+        if (chain != firewall_chain_none_id_e && action != firewall_action_none_id_e) {
+          status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+          if (F_status_is_error(status)) break;
+
+          arguments.array[arguments.used].used = 0;
+
+          if (action == firewall_action_append_id_e) {
+            status = f_string_dynamic_append(firewall_action_append_command_s, &arguments.array[arguments.used]);
+          }
+          else if (action == firewall_action_insert_id_e) {
+            status = f_string_dynamic_append(firewall_action_insert_command_s, &arguments.array[arguments.used]);
+          }
+          else if (action == firewall_action_policy_id_e) {
+            status = f_string_dynamic_append(firewall_action_policy_command_s, &arguments.array[arguments.used]);
+          }
+
+          if (F_status_is_error(status)) break;
+
+          if (action == firewall_action_append_id_e || action == firewall_action_insert_id_e || action == firewall_action_policy_id_e) {
+            ++arguments.used;
+
+            status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+            if (F_status_is_error(status)) break;
+
+            arguments.array[arguments.used].used = 0;
+            status = F_data_not;
+
+            // Process the chain, which is required by the action.
+            if (chain == firewall_chain_custom_id_e) {
+              status = f_string_dynamic_append(data->chains.array[local->chain_ids.array[local->chain]], &arguments.array[arguments.used]);
+            }
+            else if (chain == firewall_chain_forward_id_e) {
+              status = f_string_dynamic_append(firewall_chain_forward_s, &arguments.array[arguments.used]);
+            }
+            else if (chain == firewall_chain_postrouting_id_e) {
+              status = f_string_dynamic_append(firewall_chain_postrouting_s, &arguments.array[arguments.used]);
+            }
+            else if (chain == firewall_chain_prerouting_id_e) {
+              status = f_string_dynamic_append(firewall_chain_prerouting_s, &arguments.array[arguments.used]);
+            }
+            else if (chain == firewall_chain_input_id_e) {
+              status = f_string_dynamic_append(firewall_chain_input_s, &arguments.array[arguments.used]);
+            }
+            else if (chain == firewall_chain_output_id_e) {
+              status = f_string_dynamic_append(firewall_chain_output_s, &arguments.array[arguments.used]);
+            }
+
+            if (F_status_is_error(status)) break;
+
+            if (status == F_data_not) {
+              status = F_okay;
+            }
+            else {
+              ++arguments.used;
+            }
+          }
+        }
+
+        // Add the device if and only if a non-none direction is specified.
+        if (device.used && (direction == firewall_direction_input_id_e || direction == firewall_direction_output_id_e)) {
+          if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_device_all_s, length) == F_equal_to_not) {
+
+            status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+            if (F_status_is_error(status)) break;
+
+            arguments.array[arguments.used].used = 0;
+
+            if (direction == firewall_direction_input_id_e) {
+              status = f_string_dynamic_append(firewall_device_input_command_s, &arguments.array[arguments.used]);
+
+              if (F_status_is_error(status)) break;
+
+              ++arguments.used;
+            }
+            else if (direction == firewall_direction_output_id_e) {
+              status = f_string_dynamic_append(firewall_device_output_command_s, &arguments.array[arguments.used]);
+
+              if (F_status_is_error(status)) break;
+
+              ++arguments.used;
+            }
+          }
+
+          // Add the device.
+          if (device.used) {
+            status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+            if (F_status_is_error(status)) break;
+
+            arguments.array[arguments.used].used = 0;
+
+            status = f_string_dynamic_append(device, &arguments.array[arguments.used]);
+
+            if (F_status_is_error(status)) break;
+
+            ++arguments.used;
+          }
+        }
+
+        if (use_protocol) {
+          status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+          if (F_status_is_error(status)) break;
+
+          arguments.array[arguments.used].used = 0;
+
+          status = f_string_dynamic_append(firewall_protocol_command_s, &arguments.array[arguments.used]);
+
+          if (F_status_is_error(status)) break;
+
+          ++arguments.used;
+
+          if (protocol.used) {
+            status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+            if (F_status_is_error(status)) break;
+
+            arguments.array[arguments.used].used = 0;
+
+            status = f_string_dynamic_append(protocol, &arguments.array[arguments.used]);
+
+            if (F_status_is_error(status)) break;
+
+            ++arguments.used;
+          }
+        }
+
+        // Last up is the "rule".
+        if ((!is_ip_list && local->rule_contents.array[i].used > 0) || (is_ip_list && local->rule_contents.array[i].used > 1)) {
+          f_number_unsigned_t subcounter = 0;
+
+          if (is_ip_list) {
+
+            // Skip past the chain.
+            ++subcounter;
+
+            length = (local->rule_contents.array[i].array[subcounter].stop - local->rule_contents.array[i].array[subcounter].start) + 1;
+
+            if (length) {
+              ip_list.used = 0;
+
+              status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[subcounter], &ip_list);
+
+              if (F_status_is_error(status)) {
+
+                // Prevent the loop below from being processed.
+                subcounter = local->rule_contents.array[i].used;
+              }
+              else {
+                ++subcounter;
+              }
+            }
+          }
+
+          status = f_memory_array_increase_by(local->rule_contents.array[i].used, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+          if (F_status_is_error(status)) break;
+
+          for (; subcounter < local->rule_contents.array[i].used; ++subcounter) {
+
+            length = (local->rule_contents.array[i].array[subcounter].stop - local->rule_contents.array[i].array[subcounter].start) + 1;
+
+            if (length) {
+              arguments.array[arguments.used].used = 0;
+
+              status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[subcounter], &arguments.array[arguments.used]);
+              if (F_status_is_error(status)) break;
+
+              ++arguments.used;
+            }
+          } // for
+        }
+        else {
+          length = (local->rule_objects.array[i].stop - local->rule_objects.array[i].start) + 1;
+
+          f_file_stream_lock(data->main->warning.to);
+
+          fl_print_format("%r%[%QAt line %ul, the object '%]", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context);
+          fl_print_format(f_string_format_Q_range_single_s.string, data->main->warning.to, data->main->warning.notable, local->buffer, local->rule_objects.array[i], data->main->warning.notable);
+          fl_print_format("%]%[' has no content.%]%r", data->main->warning.to, data->main->warning.context, data->main->warning.context, f_string_eol_s);
+
+          f_file_stream_unlock(data->main->warning.to);
+
+          break;
+        }
+
+        // Now execute the generated commands.
+        if (arguments.used > 1) {
+          if (is_ip_list) {
+            f_file_t file = f_file_t_initialize;
+            f_string_dynamic_t path_file = f_string_dynamic_t_initialize;
+            f_string_dynamic_t local_buffer = f_string_dynamic_t_initialize;
+
+            f_ranges_t basic_objects = f_ranges_t_initialize;
+            f_rangess_t basic_contents = f_ranges_t_initialize;
+
+            status = f_string_dynamic_append(firewall_network_path_s, &path_file);
+
+            if (F_status_is_error_not(status)) {
+              status = f_string_dynamic_append(ip_list, &path_file);
+            }
+
+            if (F_status_is_error_not(status)) {
+              status = f_file_open(path_file, 0, &file);
+            }
+
+            if (F_status_is_error(status)) {
+              if (F_status_set_fine(status) == F_parameter) {
+                if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
+                  firewall_print_error_on_invalid_parameter(data->main->error, "f_file_open");
+                }
+              }
+              else if (F_status_set_fine(status) == F_file_found_not) {
+
+                // The file does not have to exist
+                if (data->main->error.verbosity != f_console_verbosity_verbose_e || data->main->error.verbosity == f_console_verbosity_debug_e) {
+                  fll_print_format("%r%[%QCannot find the file '%Q'.%]%r", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, path_file, data->main->warning.context, f_string_eol_s);
+                }
+
+                status = F_okay;
+              }
+              else if (F_status_set_fine(status) == F_file_open) {
+                if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
+                  fll_print_format("%r%[%QUnable to open the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
+                }
+              }
+              else if (F_status_set_fine(status) == F_file_descriptor) {
+                if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
+                  fll_print_format("%r%[%QFile descriptor error while trying to open the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
+                }
+              }
+              else if (F_status_set_fine(status) == F_memory_not) {
+                firewall_print_error_on_allocation_failure(data->main->error);
+              }
+              else {
+                firewall_print_error_on_unhandled(data->main->error, "f_file_open", F_status_set_fine(status));
+              }
+
+              f_file_stream_flush(file);
+              f_file_stream_close(&file);
+            }
+            else {
+              status = f_file_read(file, &local_buffer);
+
+              f_file_stream_flush(file);
+              f_file_stream_close(&file);
+
+              if (F_status_is_error(status)) {
+                if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
+                  if (F_status_set_fine(status) == F_parameter) {
+                    firewall_print_error_on_invalid_parameter(data->main->error, "f_file_read");
+                  }
+                  else if (F_status_set_fine(status) == F_number_overflow) {
+                    fll_print_format("%r%[%QInteger overflow while trying to buffer the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
+                  }
+                  else if (F_status_set_fine(status) == F_file_closed) {
+                    fll_print_format("%r%[%QThe file '%Q' is no longer open.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
+                  }
+                  else if (F_status_set_fine(status) == F_file_seek) {
+                    fll_print_format("%r%[%QA seek error occurred while accessing the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
+                  }
+                  else if (F_status_set_fine(status) == F_file_read) {
+                    fll_print_format("%r%[%QA read error occurred while accessing the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
+                  }
+                  else if (F_status_set_fine(status) != F_memory_not) {
+                    firewall_print_error_on_unhandled(data->main->error, "f_file_read", F_status_set_fine(status));
+                  }
+                }
+              }
+              else {
+                f_number_unsigneds_t delimits = f_number_unsigneds_t_initialize;
+
+                {
+                  f_state_t state = f_state_t_initialize;
+                  f_range_t input = macro_f_range_t_initialize_2(local_buffer.used);
+
+                  status = fll_fss_basic_read(local_buffer, state, &input, &basic_objects, &basic_contents, 0, &delimits, 0);
+                }
+
+                if (F_status_set_error(status)) {
+                  status = F_status_set_fine(status);
+
+                  if (status == F_parameter) {
+                    firewall_print_error_on_invalid_parameter_for_file(data->main->error, "fll_fss_basic_read", path_file.used ? path_file : f_string_empty_s);
+                  }
+                  else if (status == F_data_not_eos || status == F_data_not || status == F_data_not_stop) {
+                    // Empty files are to be silently ignored.
+                  }
+                  else if (status != F_memory_not) {
+                    firewall_print_error_on_unhandled_for_file(data->main->error, "fll_fss_basic_read", status, path_file.used ? path_file : f_string_empty_s);
+                  }
+
+                  status = F_status_set_error(status);
+                }
+
+                if (F_status_is_error_not(status)) {
+                  f_state_t state = f_state_t_initialize;
+
+                  status = f_fss_apply_delimit(state, delimits, &local_buffer);
+
+                  if (F_status_is_error(status)) {
+                    fll_error_print(data->main->error, F_status_set_fine(status), "f_fss_apply_delimit", fll_error_file_flag_fallback_e);
+                  }
+                }
+
+                if (F_status_is_error_not(status)) {
+                  status = f_memory_array_increase_by(2, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
+
+                  if (F_status_is_error_not(status)) {
+                    arguments.array[arguments.used].used = 0;
+
+                    if (ip_list_direction) {
+                      status = f_string_dynamic_append(firewall_ip_list_destination_action_s, &arguments.array[arguments.used]);
+                    }
+                    else {
+                      status = f_string_dynamic_append(firewall_ip_list_source_action_s, &arguments.array[arguments.used]);
+                    }
+                  }
+
+                  if (F_status_is_error(status)) {
+                    f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
+
+                    break;
+                  }
+
+                  ++arguments.used;
+
+                  // The ip_list file contains objects and no content, all objects are what matter an nothing else.
+                  for (f_number_unsigned_t at = 0; at < basic_objects.used; ++at) {
+
+                    arguments.array[arguments.used].used = 0;
+
+                    status = f_string_dynamic_partial_append(local_buffer, basic_objects.array[at], &arguments.array[arguments.used]);
+                    if (F_status_is_error(status)) break;
+
+                    ++arguments.used;
+
+                    firewall_print_debug_tool(data->main->warning, current_tool, arguments);
+
+                    status = fll_execute_program(current_tool, arguments, 0, 0, (void *) &return_code);
+
+                    if (status == F_child) {
+                      f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
+                      f_memory_array_resize(0, sizeof(f_char_t), (void **) &ip_list.string, &ip_list.used, &ip_list.size);
+                      f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
+                      f_memory_array_resize(0, sizeof(f_char_t), (void **) &protocol.string, &protocol.used, &protocol.size);
+
+                      f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+
+                      data->main->child = return_code;
+
+                      return status;
+                    }
+
+                    // Remove ip_argument from arguments string.
+                    --arguments.used;
+
+                    if (F_status_is_error(status)) {
+                      if (F_status_set_fine(status) == F_failure) {
+                        firewall_print_error_operation(data->main->error, current_tool, arguments);
+                      }
+                      else if (F_status_set_fine(status) == F_parameter) {
+                        firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
+                      }
+                      else {
+                        firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
+                      }
+
+                      break;
+                    }
+                  } // for
+
+                  // Remove ip_list_action from arguments string.
+                  --arguments.used;
+                }
+
+                f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
+              }
+            }
+
+            f_memory_array_resize(0, sizeof(f_char_t), (void **) &local_buffer.string, &local_buffer.used, &local_buffer.size);
+            f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+
+            f_memory_array_resize(0, sizeof(f_range_t), (void **) &basic_objects.array, &basic_objects.used, &basic_objects.size);
+            f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &basic_contents.array, &basic_contents.used, &basic_contents.size, &f_rangess_delete_callback);
+
+            if (F_status_set_fine(status) == F_failure || F_status_set_fine(status) == F_parameter) break;
+          }
+          else {
+            firewall_print_debug_tool(data->main->warning, current_tool, arguments);
+
+            status = fll_execute_program(current_tool, arguments, 0, 0, (void *) &return_code);
+
+            if (status == F_child) {
+              f_memory_array_resize(0, sizeof(f_char_t), (void **) &ip_list.string, &ip_list.used, &ip_list.size);
+              f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
+              f_memory_array_resize(0, sizeof(f_char_t), (void **) &protocol.string, &protocol.used, &protocol.size);
+
+              f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+
+              data->main->child = return_code;
+
+              return status;
+            }
+
+            if (F_status_is_error(status)) {
+              if (F_status_set_fine(status) == F_failure) {
+                firewall_print_error_operation(data->main->error, current_tool, arguments);
+              }
+              else if (F_status_set_fine(status) == F_parameter) {
+                firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
+              }
+              else if (F_status_set_fine(status) != F_memory_not) {
+                firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
+              }
+
+              break;
+            }
+          }
+        }
+      } // for
+    } // for
+
+    if (F_status_is_error(status)) {
+      if (F_status_set_fine(status) == F_memory_not) {
+        firewall_print_error_on_allocation_failure(data->main->error);
+      }
+    }
+
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &ip_list.string, &ip_list.used, &ip_list.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &protocol.string, &protocol.used, &protocol.size);
+
+    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+
+    return status;
+  }
+#endif // _di_firewall_operate_process_rules_perform_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/operate/process.h b/level_3/firewall/c/main/operate/process.h
new file mode 100644 (file)
index 0000000..d3a612a
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the process functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_operate_process_h
+#define _firewall_operate_process_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Process the loaded firewall rules.
+ *
+ * @param main
+ *   The main program and setting data.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *
+ *     F_interrupt (with error bit) on interrupt signal received.
+ *
+ *     Errors (with error bit) from: firewall_operate_process_rules_perform()
+ *
+ * @see firewall_operate_process_rules_perform()
+ */
+#ifndef _di_firewall_operate_process_rules_
+  extern void firewall_operate_process_rules(firewall_main_t * const main);
+#endif // _di_firewall_operate_process_rules_
+
+/**
+ * Perforrm the loaded firewall rules.
+ *
+ * @param main
+ *   The main program and setting data.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *
+ *     F_interrupt (with error bit) on interrupt signal received.
+ *
+ *     Errors (with error bit) from: ()
+ *
+ * @see ()
+ */
+#ifndef _di_firewall_operate_process_rules_perform_
+  extern f_status_t firewall_operate_process_rules_perform(firewall_main_t * const main);
+#endif // _di_firewall_operate_process_rules_perform_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_operate_process_h
diff --git a/level_3/firewall/c/main/print/data.c b/level_3/firewall/c/main/print/data.c
new file mode 100644 (file)
index 0000000..9bcd373
--- /dev/null
@@ -0,0 +1,9 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/print/data.h b/level_3/firewall/c/main/print/data.h
new file mode 100644 (file)
index 0000000..7b1da58
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the print data functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_print_data_h
+#define _firewall_print_data_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_print_data_h
diff --git a/level_3/firewall/c/main/print/debug.c b/level_3/firewall/c/main/print/debug.c
new file mode 100644 (file)
index 0000000..d310f21
--- /dev/null
@@ -0,0 +1,28 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_print_debug_tool_
+  void firewall_print_debug_tool(const fl_print_t output, const f_string_static_t tool, const f_string_statics_t arguments) {
+
+    if (output.verbosity != f_console_verbosity_debug_e) return;
+
+    f_file_stream_lock(output.to);
+
+    fl_print_format("%[%r", output.to, output.context, tool);
+
+    for (f_number_unsigned_t i = 0; i < arguments.used; ++i) {
+      fl_print_format(" %Q", output.to, arguments.array[i]);
+    } // for
+
+    fl_print_format("%]%r", output.to, output.context, f_string_eol_s);
+
+    f_file_stream_unlock(output.to);
+  }
+#endif // _di_firewall_print_debug_tool_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/print/debug.h b/level_3/firewall/c/main/print/debug.h
new file mode 100644 (file)
index 0000000..84a8f0a
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the print debug functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_print_debug_h
+#define _firewall_print_debug_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print debug information about tool execution.
+ *
+ * @param output
+ *   The output to print to.
+ * @param tool
+ *   The iptables tool.
+ * @param arguments
+ *   The arguments passed to the tool.
+ */
+#ifndef _di_firewall_print_debug_tool_
+  extern void firewall_print_debug_tool(const fl_print_t output, const f_string_static_t tool, const f_string_statics_t arguments);
+#endif // _di_firewall_print_debug_tool_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_print_debug_h
diff --git a/level_3/firewall/c/main/print/error.c b/level_3/firewall/c/main/print/error.c
new file mode 100644 (file)
index 0000000..2ce2b5e
--- /dev/null
@@ -0,0 +1,192 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_print_error_
+  f_status_t firewall_print_error(fl_print_t * const print, const f_string_t function) {
+
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    fll_error_print(print, F_status_set_fine(((firewall_main_t *) print->custom)->setting.state.status), function, fll_error_file_flag_fallback_e);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_error_
+
+#ifndef _di_firewall_print_error_file_
+  f_status_t firewall_print_error_file(fl_print_t * const print, const f_string_t function, const f_string_static_t name, const f_string_static_t operation, const uint8_t type) {
+
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    firewall_main_t * const main = (firewall_main_t *) print->custom;
+
+    fll_error_file_print(print, F_status_set_fine(main->setting.state.status), function, fll_error_file_flag_fallback_e, name, operation, type);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_error_file_
+
+#ifndef _di_firewall_print_error_network_device_none_
+  f_status_t firewall_print_error_network_device_none(fl_print_t * const print) {
+
+    if (!print) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    fll_print_format("%[%QCould not find any network devices.%]%r", print->to, print->context, print->prefix, print->context, f_string_eol_s);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_error_network_device_none_
+
+#ifndef _di_firewall_print_error_on_invalid_parameter_
+  void firewall_print_error_on_invalid_parameter(const fl_print_t output, const f_string_t function) {
+
+    if (output.verbosity == f_console_verbosity_quiet_e) return;
+
+    fll_print_format("%r%[%QInvalid parameter when calling %s().%]%r", print->to, f_string_eol_s, print->context, output.prefix, function, print->context, f_string_eol_s);
+  }
+#endif // _di_firewall_print_error_on_invalid_parameter_
+
+#ifndef _di_firewall_print_error_on_invalid_parameter_
+  void firewall_print_error_on_invalid_parameter_for_file(const fl_print_t output, const f_string_t function, const f_string_static_t filename) {
+
+    if (output.verbosity == f_console_verbosity_quiet_e) return;
+
+    fll_print_format("%r%[%QInvalid parameter when calling %s() for the file '%Q'.%]%r", print->to, f_string_eol_s, print->context, output.prefix, function, filename, print->context, f_string_eol_s);
+  }
+#endif // _di_firewall_print_error_on_invalid_parameter_
+
+#ifndef _di_firewall_print_error_unhandled_
+  void firewall_print_error_unhandled(const fl_print_t print, const f_string_t function, const f_string_static_t file) {
+
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    f_file_stream_lock(print->to);
+
+    firewall_main_t * const main = (firewall_main_t *) print->custom);
+
+    fl_print_format("%[%QAn unhandled error (%]", print->to, f_string_eol_s, print->context, print->prefix, print->context);
+
+    fl_print_format(f_string_format_ui_single_s.string, print->to, print->notable, F_status_set_fine(main->setting.state.status), print->notable);
+    fl_print_format("%[) has occurred while calling%] ", print->to, print->context, print->prefix, print->context);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, operation, print->notable);
+
+    if (file.used) {
+      fl_print_format("%[() for the file%] ", print->to, print->context, print->prefix, print->context);
+      fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, file, print->notable);
+      fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
+    }
+    else {
+      fl_print_format("%[().%]%r", print->to, print->context, print->context, f_string_eol_s);
+    }
+
+    f_file_stream_unlock(print->to);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_error_unhandled_
+
+#ifndef _di_firewall_print_error_operation_
+  void firewall_print_error_operation(const fl_print_t output, const f_string_static_t tool, const f_string_statics_t arguments) {
+
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    firewall_main_t * const main = (firewall_main_t *) print->custom);
+
+    if (output.verbosity == f_console_verbosity_quiet_e) return;
+
+    f_file_stream_lock(print->to);
+
+    if (F_status_set_fine(main->setting.state.status) == F_memory_not) {
+      fl_print_format("%[%QOut of memory while performing requested %r operation:%]", print->to, print->context, output.prefix, tool, print->context);
+    }
+    else {
+      fl_print_format("%[%QFailed to perform requested %r operation:%]", print->to, print->context, output.prefix, tool, print->context);
+    }
+
+    fl_print_format("%r  %[%Q", print->to, f_string_eol_s, print->context, tool);
+
+    for (f_number_unsigned_t i = 0; i < arguments.used; ++i) {
+      fl_print_format(" %Q", print->to, arguments.array[i]);
+    } // for
+
+    fl_print_format("%[', error code%] ", print->to, print->set->error, print->set->error, f_string_eol_s);
+    fl_print_format(f_string_format_ui_single_s.string, print->to, print->set->notable, F_status_set_fine(main->setting.state.status), print->set->notable);
+    fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_error_operation_
+
+#ifndef _di_firewall_print_error_operation_files_missing_
+  f_status_t firewall_print_error_operation_files_missing(const fl_print_t print, const f_string_static_t operation, const f_string_static_t file) {
+
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+    if (print->verbosity == f_console_verbosity_quiet_e) return F_output_not;
+
+    firewall_main_t * const main = (firewall_main_t *) print->custom);
+
+    f_file_stream_lock(print->to);
+
+    fl_print_format("%[%QFailed to perform%] ", print->to, print->context, output.prefix);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, operation, print->notable);
+    fl_print_format("%[request because the%] ", print->to, print->context, print->prefix, print->context);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, operation, print->notable);
+    fl_print_format("%[instructions are missing from '%]", print->to, print->set->error, print->set->error);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, file, print->notable);
+    fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_error_operation_files_missing_
+
+#ifndef _di_firewall_print_error_operation_specified_not_
+  f_status_t firewall_print_error_operation_specified_not(fl_print_t * const print) {
+
+    if (!print) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    fll_print_format("%[%QNo operation is given.%]%r", print->to, print->context, print->prefix, print->context, f_string_eol_s);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_error_operation_specified_not_
+
+#ifndef _di_firewall_print_error_directory_read_
+  f_status_t firewall_print_error_directory_read(fl_print_t * const print, const f_string_static_t ) {
+
+    if (!print) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    fll_print_format("%[%QCould not find any network devices.%]%r", print->to, print->context, print->prefix, print->context, f_string_eol_s);
+
+    //fll_print_format("%r%[%QFailed to read the device directory '%r'.%]%r", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, firewall_network_devices_s, main->error.context, f_string_eol_s);
+
+    f_file_stream_lock(print->to);
+
+    fl_print_format("%[%QFailed to read the device directory '%]", print->to, print->context, print->prefix, print->context);
+    fl_print_format(firewall_operation_show_s.string, print->to, print->notable, option, print->notable);
+    fl_print_format(" %[option '%]", print->to, print->context, print->prefix, print->context);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, option, print->notable);
+    fl_print_format("%[' is not known.%]%r", print->to, print->context, print->context, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+    f_file_stream_flush(print->to);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_error_directory_read_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/print/error.h b/level_3/firewall/c/main/print/error.h
new file mode 100644 (file)
index 0000000..58334fa
--- /dev/null
@@ -0,0 +1,194 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the print error functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_print_error_h
+#define _firewall_print_error_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print generic error message regarding a function failing in some way.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_print()
+ */
+#ifndef _di_firewall_print_error_
+  extern f_status_t firewall_print_error(fl_print_t * const print, const f_string_t function);
+#endif // _di_firewall_print_error_
+
+/**
+ * Print file related error or warning messages.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function where the error happened.
+ *   Set to 0 to disable.
+ * @param name
+ *   The name of the file or directory.
+ * @param operation
+ *   The operation that fails, such as 'create' or 'access'.
+ * @param type
+ *   A valid file type code from the fll_error_file_type enum.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_file_print()
+ */
+#ifndef _di_firewall_print_error_file_
+  extern f_status_t firewall_print_error_file(fl_print_t * const print, const f_string_t function, const f_string_static_t name, const f_string_static_t operation, const uint8_t type);
+#endif // _di_firewall_print_error_file_
+
+/**
+ * Print error message regarding being unable to find any devices.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_print()
+ */
+#ifndef _di_firewall_print_error_network_device_none_
+  extern f_status_t firewall_print_error_network_device_none(fl_print_t * const print);
+#endif // _di_firewall_print_error_network_device_none_
+
+/**
+ * Print an invalid parameter error for the given function.
+ *
+ * @param output
+ *   The output to print to.
+ * @param function
+ *   The function that failed.
+ */
+#ifndef _di_firewall_print_error_on_invalid_parameter_
+  extern void firewall_print_error_on_invalid_parameter(const fl_print_t output, const f_string_t function, const f_string_static_t file);
+#endif // _di_firewall_print_error_on_invalid_parameter_
+
+/**
+ * Print an unhandled error for the given function.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
+ * @param file
+ *   The name of the file, if this error is assocaited with a file.
+ *   Otherwise, set file.used to 0 to not have an file related error message.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ */
+#ifndef _di_firewall_print_error_unhandled_
+  extern f_status_t firewall_print_error_unhandled(const fl_print_t print, const f_string_t function, const f_string_static_t file);
+#endif // _di_firewall_print_error_unhandled_
+
+/**
+ * Print an error about the given operation failed.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param tool
+ *   The tool, such as iptables, that failed.
+ * @param arguments
+ *   The arguments passed to the tool.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ */
+#ifndef _di_firewall_print_error_operation_
+  extern f_status_t firewall_print_error_operation(const fl_print_t print, const f_string_static_t tool, const f_string_statics_t arguments);
+#endif // _di_firewall_print_error_operation_
+
+/**
+ * Print an error about the operation setting missing from the file.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param operation
+ *   The operation setting that is missing from the file.
+ *   This is also the name of the operation itself.
+ * @param file
+ *   The file that is missing the operation.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ */
+#ifndef _di_firewall_print_error_operation_files_missing_
+  extern f_status_t firewall_print_error_operation_files_missing(const fl_print_t print, const f_string_static_t operation, const f_string_static_t file);
+#endif // _di_firewall_print_error_operation_files_missing_
+
+/**
+ * Print generic error message regarding a function failing in some way.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_print()
+ */
+#ifndef _di_firewall_print_error_operation_specified_not_
+  extern f_status_t firewall_print_error_operation_specified_not(fl_print_t * const print);
+#endif // _di_firewall_print_error_operation_specified_not_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_print_error_h
diff --git a/level_3/firewall/c/main/print/message.c b/level_3/firewall/c/main/print/message.c
new file mode 100644 (file)
index 0000000..71507b9
--- /dev/null
@@ -0,0 +1,65 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_print_message_help_
+  f_status_t firewall_print_message_help(fl_print_t * const print) {
+
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+
+    f_file_stream_lock(print->to);
+
+    fll_program_print_help_header(print, firewall_program_name_long_s, firewall_program_version_s);
+
+    fll_program_print_help_option_standard(print);
+
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    fll_program_print_help_operations(print);
+
+    fll_program_print_help_option_other(print, firewall_operation_lock_s, "   Switch to rules intended to prevent all communication.");
+    fll_program_print_help_option_other(print, firewall_operation_restart_s, "Turn off and then turn on the firewall.");
+    fll_program_print_help_option_other(print, firewall_operation_show_s, "   Show the active firewall settings.");
+    fll_program_print_help_option_other(print, firewall_operation_start_s, "  Turn on the firewall.");
+    fll_program_print_help_option_other(print, firewall_operation_stop_s, "   Turn off the firewall.");
+
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    fll_program_print_help_usage(print, firewall_program_name_s, firewall_program_help_commands_s);
+
+    f_file_stream_flush(print->to);
+    f_file_stream_unlock(print->to);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_message_help_
+
+#ifndef _di_firewall_print_message_show_header_
+  f_status_t firewall_print_message_show_header(fl_print_t * const print, const f_string_static_t left, const f_string_static_t header, const f_string_static_t right) {
+
+    if (!print) return F_status_set_error(F_output_not);
+
+    f_file_stream_lock(print->to);
+
+    if (left.used) {
+      fl_print_format("%[%Q%] ", print->to, print->set.standout, left, print->set.standout);
+    }
+
+    fll_print_format("%[%Q%]", print->to, print->set.standout, print->set.standout, print->set.title, print->set.title, print->set.standout, print->set.standout, f_string_eol_s);
+
+    if (left.used) {
+      fl_print_format(" %[%Q%]", print->to, print->set.standout, right, print->set.standout);
+    }
+
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    f_file_stream_flush(print->to);
+    f_file_stream_unlock(print->to);
+  }
+#endif // _di_firewall_print_message_show_header_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/print/message.h b/level_3/firewall/c/main/print/message.h
new file mode 100644 (file)
index 0000000..b4d8c9e
--- /dev/null
@@ -0,0 +1,85 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the print message functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_print_message_h
+#define _firewall_print_message_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see f_file_stream_flush()
+ * @see f_file_stream_lock()
+ * @see f_file_stream_unlock()
+ * @see f_print_dynamic_raw()
+ * @see fl_print_format()
+ *
+ * @see fll_program_print_help_header()
+ * @see fll_program_print_help_option()
+ * @see fll_program_print_help_option_standard()
+ * @see fll_program_print_help_usage()
+ */
+#ifndef _di_firewall_print_message_help_
+  extern f_status_t firewall_print_message_help(fl_print_t * const print);
+#endif // _di_firewall_print_message_help_
+
+/**
+ * Print show option header.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param left
+ *   The option to show on the left side of the header text.
+ *   The left.used may be 0.
+ * @param header
+ *   The header text.
+ *   The header.used should not be 0.
+ * @param right
+ *   The option to show on the right side of the header text.
+ *   The right.used may be 0.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see f_file_stream_flush()
+ * @see f_file_stream_lock()
+ * @see f_file_stream_unlock()
+ * @see f_print_dynamic_raw()
+ * @see fl_print_format()
+ */
+#ifndef _di_firewall_print_message_show_header_
+  extern f_status_t firewall_print_message_show_header(fl_print_t * const print, const f_string_static_t left, const f_string_static_t header, const f_string_static_t right);
+#endif // _di_firewall_print_message_show_header_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_print_message_h
diff --git a/level_3/firewall/c/main/print/verbose.c b/level_3/firewall/c/main/print/verbose.c
new file mode 100644 (file)
index 0000000..9bcd373
--- /dev/null
@@ -0,0 +1,9 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/print/verbose.h b/level_3/firewall/c/main/print/verbose.h
new file mode 100644 (file)
index 0000000..f00cf0c
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the print verbose functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_print_verbose_h
+#define _firewall_print_verbose_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_print_verbose_h
diff --git a/level_3/firewall/c/main/print/warning.c b/level_3/firewall/c/main/print/warning.c
new file mode 100644 (file)
index 0000000..428cbce
--- /dev/null
@@ -0,0 +1,30 @@
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_print_warning_show_option_unknown_
+  f_status_t firewall_print_warning_show_option_unknown(fl_print_t * const print, const f_string_static_t option) {
+
+    if (!print) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_verbose_e) return F_output_not;
+
+    f_file_stream_lock(print->to);
+
+    fl_print_format("%[%QThe%] ", print->to, print->context, print->prefix, print->context);
+    fl_print_format(firewall_operation_show_s.string, print->to, print->notable, option, print->notable);
+    fl_print_format(" %[option '%]", print->to, print->context, print->prefix, print->context);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, option, print->notable);
+    fl_print_format("%[' is not known.%]%r", print->to, print->context, print->context, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+    f_file_stream_flush(print->to);
+
+    return F_okay;
+  }
+#endif // _di_firewall_print_warning_show_option_unknown_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/print/warning.h b/level_3/firewall/c/main/print/warning.h
new file mode 100644 (file)
index 0000000..0d1c509
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the print warning functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_print_warning_h
+#define _firewall_print_warning_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print warning message regarding a show option not being known.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param option
+ *   The show option that is not known.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_print()
+ */
+#ifndef _di_firewall_print_warning_show_option_unknown_
+  extern f_status_t firewall_print_warning_show_option_unknown(fl_print_t * const print, const f_string_static_t option);
+#endif // _di_firewall_print_warning_show_option_unknown_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_print_warning_h
diff --git a/level_3/firewall/c/main/signal.c b/level_3/firewall/c/main/signal.c
new file mode 100644 (file)
index 0000000..76c63fc
--- /dev/null
@@ -0,0 +1,111 @@
+#include "firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_firewall_signal_check_) && defined(_di_thread_support_)
+  f_status_t firewall_signal_check(firewall_main_t * const main) {
+
+    if (!main || main->program.signal.id == -1) return F_false;
+
+    if (!((++main->program.signal_check) % firewall_signal_check_d)) {
+      if (fll_program_standard_signal_received(&main->program)) {
+        fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
+
+        main->setting.state.status = F_status_set_error(F_interrupt);
+
+        return F_true;
+      }
+
+      main->program.signal_check = 0;
+    }
+
+    return F_false;
+  }
+#endif // !defined(_di_firewall_signal_check_) && defined(_di_thread_support_)
+
+#if !defined(_di_firewall_signal_check_) && !defined(_di_thread_support_)
+  f_status_t firewall_signal_check(firewall_main_t * const main) {
+
+    if (!main || main->program.signal.id == -1) return F_false;
+
+    if (main->program.signal_received) {
+      fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
+
+      main->setting.state.status = F_status_set_error(F_interrupt);
+
+      return F_true;
+    }
+
+    return F_false;
+  }
+#endif // !defined(_di_firewall_signal_check_) && !defined(_di_thread_support_)
+
+#if !defined(_di_firewall_signal_handler_) && !defined(_di_thread_support_)
+  void firewall_signal_handler(firewall_main_t * const main) {
+
+    if (!main) return;
+
+    siginfo_t information;
+    f_number_unsigned_t failsafe = 0;
+
+    memset(&information, 0, sizeof(siginfo_t));
+
+    main->program.signal_received = 0;
+
+    f_signal_set_empty(&main->program.signal.set);
+    f_signal_set_add(F_signal_abort, &main->program.signal.set);
+    f_signal_set_add(F_signal_broken_pipe, &main->program.signal.set);
+    f_signal_set_add(F_signal_hangup, &main->program.signal.set);
+    f_signal_set_add(F_signal_interrupt, &main->program.signal.set);
+    f_signal_set_add(F_signal_quit, &main->program.signal.set);
+    f_signal_set_add(F_signal_termination, &main->program.signal.set);
+
+    if (main->program.signal.id == -1) {
+      main->setting.status_signal = f_signal_open(&main->program.signal);
+
+      if (F_status_is_error(main->setting.status_signal)) {
+        main->program.signal_received = F_signal_abort;
+
+        return;
+      }
+    }
+
+    do {
+      memset(&information, 0, sizeof(siginfo_t));
+
+      main->setting.status_signal = f_signal_wait(&main->program.signal.set, &information);
+
+      if (F_status_is_error(main->setting.status_signal) && F_status_set_fine(main->setting.status_signal) != F_interrupt) {
+        if (++failsafe >= firewall_signal_check_failsafe_d) break;
+      }
+
+      switch (information.si_signo) {
+        case F_signal_abort:
+        case F_signal_broken_pipe:
+        case F_signal_hangup:
+        case F_signal_interrupt:
+        case F_signal_quit:
+        case F_signal_termination:
+          main->program.signal_received = information.si_signo;
+
+          break;
+      }
+
+      failsafe = 0;
+      main->setting.status_signal = F_okay;
+
+    } while (!main->program.signal_received);
+
+    f_signal_close(&main->program.signal);
+
+    if (F_status_is_error(main->setting.status_signal)) {
+      main->program.signal_received = F_signal_abort;
+    }
+  }
+#endif // !defined(_di_firewall_signal_handler_) && !defined(_di_thread_support_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/signal.h b/level_3/firewall/c/main/signal.h
new file mode 100644 (file)
index 0000000..49156e3
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides signal functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_signal_h
+#define _firewall_signal_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Check to see if a signal is received.
+ *
+ * If main.signal is non-zero, then this handles the following signals:
+ *   - F_signal_abort
+ *   - F_signal_broken_pipe
+ *   - F_signal_hangup
+ *   - F_signal_interrupt
+ *   - F_signal_quit
+ *   - F_signal_termination
+ *
+ * There is a threaded and a non-threaded version of this.
+ * The non-threaded version checks periodically using firewall_signal_check_d and updates main->signal_check as needed.
+ * The threaded version checks the flag state which is set by a separate thread that is blocking until signal is received.
+ *
+ * @param main
+ *   The main program and settings data.
+ *
+ *   This does not alter main.setting.state.status.
+ *
+ * @return
+ *   F_true on signal received.
+ *   F_false otherwise.
+ *
+ * @see firewall_signal_handler()
+ *
+ * @see fll_program_standard_signal_received()
+ */
+#ifndef _di_firewall_signal_check_
+  extern f_status_t firewall_signal_check(firewall_main_t * const main);
+#endif // _di_firewall_signal_check_
+
+/**
+ * Signal handler for signals/interrupts.
+ *
+ * This blocks until an expected signal is recieved.
+ * When an expected signal is received it then sets the
+ *
+ * If main.signal is non-zero, then this handles the following signals:
+ *   - F_signal_abort
+ *   - F_signal_broken_pipe
+ *   - F_signal_hangup
+ *   - F_signal_interrupt
+ *   - F_signal_quit
+ *   - F_signal_termination
+ *
+ * @param main
+ *   The main program and settings data.
+ *
+ *   This alters main.program.signal_received, setting it to a received signal.
+ *
+ *   This alters main.setting.state.status:
+ *     Errors (with error bit) from: f_signal_open()
+ *     Errors (with error bit) from: f_signal_wait()
+ *
+ * @see f_signal_close()
+ * @see f_signal_open()
+ * @see f_signal_wait()
+ */
+#if !defined(_di_firewall_signal_handler_) && !defined(_di_thread_support_)
+  extern void firewall_signal_handler(firewall_main_t * const main);
+#endif // !defined(_di_firewall_signal_handler_) && !defined(_di_thread_support_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_signal_h
diff --git a/level_3/firewall/c/main/thread.c b/level_3/firewall/c/main/thread.c
new file mode 100644 (file)
index 0000000..b8803f5
--- /dev/null
@@ -0,0 +1,22 @@
+#include "firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_firewall_thread_signal_) && !defined(_di_thread_support_)
+  void * firewall_thread_signal(void * const main) {
+
+    f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
+
+    if (main) {
+      firewall_signal_handler((firewall_main_t *) main);
+    }
+
+    return 0;
+  }
+#endif // !defined(_di_firewall_thread_signal_) && !defined(_di_thread_support_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_3/firewall/c/main/thread.h b/level_3/firewall/c/main/thread.h
new file mode 100644 (file)
index 0000000..12f6483
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides thread functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _firewall_thread_h
+#define _firewall_thread_h
+
+/**
+ * Thread handler for signals/interrupts.
+ *
+ * If main.signal is non-zero, then this handles the following signals:
+ *   - F_signal_abort
+ *   - F_signal_broken_pipe
+ *   - F_signal_hangup
+ *   - F_signal_interrupt
+ *   - F_signal_quit
+ *   - F_signal_termination
+ *
+ * @param main
+ *   The program and settings data.
+ *
+ *   Must be of type firewall_main_t.
+ *
+ * @return
+ *   0, always.
+ *
+ * @see f_thread_cancel_state_set()
+ *
+ * @see firewall_signal_handler()
+ */
+#if !defined(_di_firewall_thread_signal_) && !defined(_di_thread_support_)
+  extern void * firewall_thread_signal(void * const main);
+#endif // !defined(_di_firewall_thread_signal_) && !defined(_di_thread_support_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_thread_h
diff --git a/level_3/firewall/c/print.c b/level_3/firewall/c/print.c
deleted file mode 100644 (file)
index 1a625d4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "firewall.h"
-#include "private-common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _di_firewall_print_help_
-  f_status_t firewall_print_help(firewall_setting_t * const setting, const fl_print_t print) {
-
-    f_file_stream_lock(print.to);
-
-    fll_program_print_help_header(print, firewall_program_name_long_s, firewall_program_version_s);
-
-    fll_program_print_help_option_standard(print);
-
-    fl_print_format("%r%r %[Commands:%] ", print.to, f_string_eol_s, f_string_eol_s, print.set->important, print.set->important);
-    fl_print_format("%r  %[%r%]    Turn on the firewall.", print.to, f_string_eol_s, print.set->standout, firewall_command_start_s, print.set->standout);
-    fl_print_format("%r  %[%r%]     Turn off the firewall.", print.to, f_string_eol_s, print.set->standout, firewall_command_stop_s, print.set->standout);
-    fl_print_format("%r  %[%r%]  Turn off and then turn on the firewall.", print.to, f_string_eol_s, print.set->standout, firewall_command_restart_s, print.set->standout);
-    fl_print_format("%r  %[%r%]     Prevent all communication.", print.to, f_string_eol_s, print.set->standout, firewall_command_lock_s, print.set->standout);
-    fl_print_format("%r  %[%r%]     Show active firewall settings.", print.to, f_string_eol_s, print.set->standout, firewall_command_show_s, print.set->standout);
-
-    f_print_dynamic_raw(f_string_eol_s, print.to);
-    f_print_dynamic_raw(f_string_eol_s, print.to);
-
-    fll_program_print_help_usage(print, firewall_program_name_s, firewall_program_help_parameters_s);
-
-    f_file_stream_flush(print.to);
-    f_file_stream_unlock(print.to);
-
-    return F_okay;
-  }
-#endif // _di_firewall_print_help_
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/level_3/firewall/c/print.h b/level_3/firewall/c/print.h
deleted file mode 100644 (file)
index 6db7e94..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * FLL - Level 3
- *
- * Project: Firewall
- * API Version: 0.7
- * Licenses: lgpl-2.1-or-later
- */
-#ifndef _firewall_print_h
-#define _firewall_print_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Print help.
- *
- * @param setting
- *   The main program settings.
- *
- *   This does not alter setting.state.status.
- * @param print
- *   The output structure to print to.
- *
- * @return
- *   F_okay on success.
- */
-#ifndef _di_firewall_print_help_
-  extern f_status_t firewall_print_help(firewall_setting_t * const setting, const fl_print_t print);
-#endif // _di_firewall_print_help_
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // _firewall_print_h
diff --git a/level_3/firewall/c/private-common.c b/level_3/firewall/c/private-common.c
deleted file mode 100644 (file)
index 0c08398..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "firewall.h"
-#include "private-common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _di_firewall_data_delete_
-  f_status_t firewall_data_delete(firewall_data_t * const data) {
-
-    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &data->chains.string, &data->chains.used, &data->chains.size, &f_string_dynamics_delete_callback);
-    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &data->devices.string, &data->devices.used, &data->devices.size, &f_string_dynamics_delete_callback);
-
-    return F_okay;
-  }
-#endif // _di_firewall_data_delete_
-
-void firewall_print_debug_tool(const fl_print_t output, const f_string_static_t tool, const f_string_statics_t arguments) {
-
-  if (output.verbosity != f_console_verbosity_debug_e) return;
-
-  f_file_stream_lock(output.to);
-
-  fl_print_format("%[%r", output.to, output.context, tool);
-
-  for (f_number_unsigned_t i = 0; i < arguments.used; ++i) {
-    fl_print_format(" %Q", output.to, arguments.array[i]);
-  } // for
-
-  fl_print_format("%]%r", output.to, output.context, f_string_eol_s);
-
-  f_file_stream_unlock(output.to);
-}
-
-void firewall_print_error_on_allocation_failure(const fl_print_t output) {
-
-  if (output.verbosity == f_console_verbosity_quiet_e) return;
-
-  fll_print_format("%r%[%QUnable to allocate memory.%]%r", output.to, f_string_eol_s, output.context, output.prefix, output.context, f_string_eol_s);
-}
-
-void firewall_print_error_on_invalid_parameter(const fl_print_t output, const f_string_t function) {
-
-  if (output.verbosity == f_console_verbosity_quiet_e) return;
-
-  fll_print_format("%r%[%QInvalid parameter when calling %s().%]%r", output.to, f_string_eol_s, output.context, output.prefix, function, output.context, f_string_eol_s);
-}
-
-void firewall_print_error_on_invalid_parameter_for_file(const fl_print_t output, const f_string_t function, const f_string_static_t filename) {
-
-  if (output.verbosity == f_console_verbosity_quiet_e) return;
-
-  fll_print_format("%r%[%QInvalid parameter when calling %s() for the file '%Q'.%]%r", output.to, f_string_eol_s, output.context, output.prefix, function, filename, output.context, f_string_eol_s);
-}
-
-void firewall_print_error_on_operation(const fl_print_t output, const f_string_static_t tool, const f_string_statics_t arguments) {
-
-  if (output.verbosity == f_console_verbosity_quiet_e) return;
-
-  f_file_stream_lock(output.to);
-
-  fl_print_format("%r%[%QFailed to perform requested %r operation:%]", output.to, f_string_eol_s, output.context, output.prefix, tool, output.context);
-  fl_print_format("%r  %[%r", output.to, f_string_eol_s, output.context, tool);
-
-  for (f_number_unsigned_t i = 0; i < arguments.used; ++i) {
-    fl_print_format(" %Q", output.to, arguments.array[i]);
-  } // for
-
-  fl_print_format("%]%r", output.to, output.context, f_string_eol_s);
-
-  f_file_stream_unlock(output.to);
-}
-
-void firewall_print_error_on_unhandled(const fl_print_t output, const f_string_t function, const f_status_t status) {
-
-  if (output.verbosity == f_console_verbosity_quiet_e) return;
-
-  fll_print_format("%r%[%QAn unhandled error (%ui) has occurred while calling %s().%]%r", output.to, f_string_eol_s, output.context, output.prefix, status, function, output.context, f_string_eol_s);
-}
-
-void firewall_print_error_on_unhandled_for_file(const fl_print_t output, const f_string_t function, const f_status_t status, const f_string_static_t filename) {
-
-  if (output.verbosity == f_console_verbosity_quiet_e) return;
-
-  fll_print_format("%r%[%QAn unhandled error (%ui) has occurred while calling %s() for the file '%Q'.%]%r", output.to, f_string_eol_s, output.context, output.prefix, status, function, filename, output.context, f_string_eol_s);
-}
-
-#ifndef _di_firewall_signal_received_
-  f_status_t firewall_signal_received(firewall_data_t * const data) {
-
-    if (data->main->signal.id == -1) {
-      return F_false;
-    }
-
-    struct signalfd_siginfo information;
-
-    memset(&information, 0, sizeof(struct signalfd_siginfo));
-
-    if (f_signal_read(data->main->signal, 0, &information) == F_signal) {
-      switch (information.ssi_signo) {
-        case F_signal_abort:
-        case F_signal_broken_pipe:
-        case F_signal_hangup:
-        case F_signal_interrupt:
-        case F_signal_quit:
-        case F_signal_termination:
-          firewall_print_signal_received(data, information.ssi_signo);
-
-          return information.ssi_signo;
-      }
-    }
-
-    return F_false;
-  }
-#endif // _di_firewall_signal_received_
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/level_3/firewall/c/private-common.h b/level_3/firewall/c/private-common.h
deleted file mode 100644 (file)
index 67e65a3..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * FLL - Level 3
- *
- * Project: Firewall
- * API Version: 0.7
- * Licenses: lgpl-2.1-or-later
- */
-#ifndef _PRIVATE_common_h
-#define _PRIVATE_common_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
-  bool is_global;
-  bool is_main;
-  bool is_stop;
-  bool is_lock;
-
-  f_number_unsigned_t device;
-
-  f_string_dynamic_t buffer;
-  f_number_unsigned_t chain;
-  f_number_unsigneds_t chain_ids;
-  f_ranges_t chain_objects;
-  f_rangess_t chain_contents;
-  f_ranges_t rule_objects;
-  f_rangess_t rule_contents;
-} firewall_local_data_t;
-
-#define firewall_local_data_t_initialize \
-  { \
-    F_true, \
-    F_false, \
-    F_false, \
-    F_false, \
-    0, \
-    f_string_dynamic_t_initialize, \
-    0, \
-    f_number_unsigneds_t_initialize, \
-    f_ranges_t_initialize, \
-    f_rangess_t_initialize, \
-    f_ranges_t_initialize, \
-    f_rangess_t_initialize, \
-  }
-
-typedef struct {
-  bool has_main;
-  bool has_stop;
-  bool has_lock;
-
-  f_number_unsigned_t main_at;
-  f_number_unsigned_t stop_at;
-  f_number_unsigned_t lock_at;
-} firewall_reserved_chains_t;
-
-#define firewall_reserved_chains_t_initialize \
-  { \
-    F_false, \
-    F_false, \
-    F_false, \
-    0, \
-    0, \
-    0, \
-  }
-
-/**
- * The program data.
- *
- * argv:    The argument structure in the progam data parameters for simplifying syntax.
- * main:    The main program data.
- * chains:  a
- * devices: A
- */
-#ifndef _di_firewall_data_t_
-  typedef struct {
-    fll_program_data_t *main;
-    f_string_static_t *argv;
-
-    f_string_dynamics_t chains;
-    f_string_dynamics_t devices;
-  } firewall_data_t;
-
-  #define firewall_data_t_initialize \
-    { \
-      0, \
-      0, \
-      f_string_dynamics_t_initialize, \
-      f_string_dynamics_t_initialize, \
-    }
-#endif // _di_firewall_data_t_
-
-/**
- * De-allocate data.
- *
- * @param data
- *   The program data.
- *
- * @return
- *   F_okay on success.
- *
- *   Status codes (with error bit) are returned on any problem.
- *
- * @see firewall_main()
- */
-#ifndef _di_firewall_data_delete_
-  extern f_status_t firewall_data_delete(firewall_data_t * const data);
-#endif // _di_firewall_data_delete_
-
-/**
- * Print debug information about tool execution.
- *
- * @param output
- *   The output to print to.
- * @param tool
- *   The iptables tool.
- * @param arguments
- *   The arguments passed to the tool.
- */
-extern void firewall_print_debug_tool(const fl_print_t output, const f_string_static_t tool, const f_string_statics_t arguments) F_attribute_visibility_internal_d;
-
-/**
- * Print an memory allocation error.
- *
- * @param output
- *   The output to print to.
- */
-extern void firewall_print_error_on_allocation_failure(const fl_print_t output) F_attribute_visibility_internal_d;
-
-/**
- * Print an invalid parameter error for the given function.
- *
- * @param output
- *   The output to print to.
- * @param function
- *   The function that failed.
- */
-extern void firewall_print_error_on_invalid_parameter(const fl_print_t output, const f_string_t function) F_attribute_visibility_internal_d;
-
-/**
- * Print an invalid parameter error for the given function.
- *
- * @param output
- *   The output to print to.
- * @param function
- *   The function that failed.
- * @param filename
- *   The name of the file.
- */
-extern void firewall_print_error_on_invalid_parameter_for_file(const fl_print_t output, const f_string_t function, const f_string_static_t filename) F_attribute_visibility_internal_d;
-
-/**
- * Print an error about the given operation failed.
- *
- * @param output
- *   The output to print to.
- * @param tool
- *   The iptables tool that failed.
- * @param arguments
- *   The arguments passed to the tool.
- */
-extern void firewall_print_error_on_operation(const fl_print_t output, const f_string_static_t tool, const f_string_statics_t arguments) F_attribute_visibility_internal_d;
-
-/**
- * Print an unhandled error for the given function.
- *
- * @param output
- *   The output to print to.
- * @param function
- *   The function that failed.
- * @param status
- *   The failure status code.
- */
-extern void firewall_print_error_on_unhandled(const fl_print_t output, const f_string_t function, const f_status_t status) F_attribute_visibility_internal_d;
-
-/**
- * Print an unhandled error for the given function for some given file.
- *
- * @param output
- *   The output to print to.
- * @param function
- *   The function that failed.
- * @param status
- *   The failure status code.
- * @param filename
- *   The name of the file.
- */
-extern void firewall_print_error_on_unhandled_for_file(const fl_print_t output, const f_string_t function, const f_status_t status, const f_string_static_t filename) F_attribute_visibility_internal_d;
-
-/**
- * Check to see if a process signal is received.
- *
- * Only signals that are blocked via main.signal will be received.
- *
- * @param data
- *   The program data.
- *
- * @return
- *   A positive number representing a valid signal on signal received.
- *   F_false on no signal received.
- *
- * @see f_signal_read()
- */
-#ifndef _di_firewall_signal_received_
-  extern f_status_t firewall_signal_received(firewall_data_t * const data) F_attribute_visibility_internal_d;
-#endif // _di_firewall_signal_received_
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // _PRIVATE_common_h
diff --git a/level_3/firewall/c/private-firewall.c b/level_3/firewall/c/private-firewall.c
deleted file mode 100644 (file)
index f8826af..0000000
+++ /dev/null
@@ -1,1315 +0,0 @@
-#include "firewall.h"
-#include "private-common.h"
-#include "private-firewall.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-f_status_t firewall_perform_commands(firewall_data_t * const data, firewall_local_data_t * const local) {
-
-  if (!data || !local || local->device >= data->devices.used) return F_status_set_error(F_parameter);
-
-  f_status_t status = F_okay;
-
-  bool invalid = F_false;
-  bool is_ip_list = F_false;
-
-  // Iptables command arguments
-  bool ip_list_direction = F_false; // false = source, true = destination.
-  bool use_protocol = F_false;
-  uint8_t tool = firewall_program_ip46tables_e;
-  uint8_t chain = firewall_chain_none_id_e;
-
-  int return_code = 0;
-
-  f_number_unsigned_t i = 0;
-  f_number_unsigned_t r = 0;
-  f_number_unsigned_t repeat = 2;
-  f_number_unsigned_t length = 0;
-
-  f_string_static_t current_tool = firewall_tool_iptables_s;
-
-  uint8_t direction = firewall_direction_none_id_e;
-  uint8_t action = firewall_action_append_id_e;
-
-  f_string_dynamic_t ip_list = f_string_dynamic_t_initialize;
-  f_string_dynamic_t device = f_string_dynamic_t_initialize;
-  f_string_dynamic_t protocol = f_string_dynamic_t_initialize;
-  f_string_dynamics_t arguments = f_string_dynamics_t_initialize;
-
-  if (!local->is_global) {
-    if (data->devices.array[local->device].used) {
-      device.used = 0;
-
-      status = f_string_dynamic_append(data->devices.array[local->device], &device);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_memory_not) {
-          firewall_print_error_on_allocation_failure(data->main->error);
-        }
-
-        return status;
-      }
-    }
-  }
-
-  // For custom chains, the chain command may not be specified.
-  if (!(local->is_main || local->is_stop || local->is_lock)) {
-    chain = firewall_chain_custom_id_e;
-  }
-
-  for (; F_status_is_error_not(status) && i < local->rule_objects.used; ++i) {
-
-    if (!((++data->main->signal_check) % firewall_signal_check_d)) {
-      if (firewall_signal_received(data)) {
-        f_memory_array_resize(0, sizeof(f_char_t), (void **) &ip_list.string, &ip_list.used, &ip_list.size);
-        f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
-        f_memory_array_resize(0, sizeof(f_char_t), (void **) &protocol.string, &protocol.used, &protocol.size);
-
-        f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
-
-        return F_status_set_error(F_interrupt);
-      }
-
-      data->main->signal_check = 0;
-    }
-
-    length = (local->rule_objects.array[i].stop - local->rule_objects.array[i].start) + 1;
-    invalid = F_false;
-
-    is_ip_list = F_false;
-    ip_list_direction = F_false;
-
-    ip_list.used = 0;
-
-    // Process chain rule.
-    if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_chain_s, length) == F_equal_to) {
-      if (chain == firewall_chain_custom_id_e) {
-
-        // Custom chains can only apply to themselves, so silently ignore chain commands specified within a custom chain.
-        fll_print_format("%r%[%QAt line %ul, the chain option is meaningless inside of a custom chain.%]%r", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context, f_string_eol_s);
-
-        continue;
-      }
-
-      length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
-
-      if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
-        invalid = F_true;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_input_s, length) == F_equal_to) {
-        chain = firewall_chain_input_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_output_s, length) == F_equal_to) {
-        chain = firewall_chain_output_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_forward_s, length) == F_equal_to) {
-        chain = firewall_chain_forward_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_postrouting_s, length) == F_equal_to) {
-        chain = firewall_chain_postrouting_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_prerouting_s, length) == F_equal_to) {
-        chain = firewall_chain_prerouting_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_chain_none_s, length) == F_equal_to) {
-        chain = firewall_chain_none_id_e;
-      }
-      else {
-        invalid = F_true;
-      }
-
-      if (!invalid) continue;
-    }
-
-    // Process direction rule
-    else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_direction_s, length) == F_equal_to) {
-      length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
-
-      if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
-        invalid = F_true;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_direction_input_s, length) == F_equal_to) {
-        direction = firewall_direction_input_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_direction_output_s, length) == F_equal_to) {
-        direction = firewall_direction_output_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_direction_none_s, length) == F_equal_to) {
-        direction = firewall_direction_none_id_e;
-      }
-      else {
-
-        // Direction must be specified, and no custom directions are allowed.
-        invalid = F_true;
-      }
-
-      if (!invalid) continue;
-    }
-
-    // Process device rule.
-    else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_device_s, length) == F_equal_to) {
-      length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
-
-      if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
-        invalid = F_true;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_device_all_s, length) == F_equal_to) {
-        f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
-
-        continue;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_device_this_s, length) == F_equal_to) {
-        if (data->devices.array[local->device].used) {
-          status = f_memory_array_increase_by(data->devices.array[local->device].used, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
-          if (F_status_is_error(status)) break;
-
-          memcpy(device.string, data->devices.array[local->device].string, sizeof(f_char_t) * data->devices.array[local->device].used);
-
-          device.used = data->devices.array[local->device].used;
-        }
-        else {
-          f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
-        }
-
-        continue;
-      }
-
-      if (!invalid) {
-        device.used = 0;
-
-        if (length) {
-          status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[0], &device);
-
-          if (F_status_is_error(status)) break;
-        }
-
-        continue;
-      }
-    }
-
-    // Process action rule.
-    else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_action_s, length) == F_equal_to) {
-      length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
-
-      if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
-        invalid = F_true;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_action_append_s, length) == F_equal_to) {
-        action = firewall_action_append_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_action_insert_s, length) == F_equal_to) {
-        action = firewall_action_insert_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_action_policy_s, length) == F_equal_to) {
-        action = firewall_action_policy_id_e;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_action_none_s, length) == F_equal_to) {
-        action = firewall_action_none_id_e;
-      }
-      else {
-        invalid = F_true;
-      }
-
-      if (!invalid) continue;
-    }
-
-    // Process ip_list rule.
-    else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_ip_list, length) == F_equal_to) {
-      length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
-      is_ip_list = F_true;
-
-      if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_ip_list_source_s, length) == F_equal_to) {
-        ip_list_direction = F_false;
-      }
-      else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_ip_list_destination_s, length) == F_equal_to) {
-        ip_list_direction = F_true;
-      }
-      else {
-        invalid = F_true;
-      }
-    }
-    else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_protocol_s, length) == F_equal_to) {
-      length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
-
-      if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
-        invalid = F_true;
-      }
-      else {
-        if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_protocol_none_s, length) == F_equal_to) {
-          use_protocol = F_false;
-        }
-        else if (length) {
-          protocol.used = 0;
-
-          status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[0], &protocol);
-
-          if (F_status_is_error(status)) break;
-
-          use_protocol = F_true;
-        }
-        else {
-          use_protocol = F_false;
-        }
-
-        continue;
-      }
-    }
-
-    // Process tool rule.
-    else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_tool_s, length) == F_equal_to) {
-      length = (local->rule_contents.array[i].array[0].stop - local->rule_contents.array[i].array[0].start) + 1;
-
-      if (local->rule_contents.array[i].used <= 0 || local->rule_contents.array[i].used > 1) {
-        invalid = F_true;
-      }
-      else {
-        if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_tool_iptables_s, length) == F_equal_to) {
-          tool = firewall_program_iptables_e;
-          current_tool = firewall_tool_iptables_s;
-          repeat = 1;
-        }
-        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_tool_ip6tables_s, length) == F_equal_to) {
-          tool = firewall_program_ip6tables_e;
-          current_tool = firewall_tool_ip6tables_s;
-          repeat = 1;
-        }
-        else if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_tool_ip46tables_s, length) == F_equal_to) {
-          tool = firewall_program_ip46tables_e;
-          current_tool = firewall_tool_iptables_s;
-          repeat = 2;
-        }
-        else {
-          invalid = F_true;
-        }
-
-        if (!invalid) continue;
-      }
-    }
-
-    // If the remaining rule does not match as firewall_rule_s, then it is an invalid rule.
-    else if (f_compare_dynamic_string(local->buffer.string + local->rule_objects.array[i].start, firewall_rule_s, length) == F_equal_to_not) {
-      if (length) {
-        f_file_stream_lock(data->main->warning.to);
-
-        fl_print_format("%r%[%QAt line %ul, the object '%]", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context, data->main->warning.notable);
-        fl_print_format(f_string_format_Q_range_single_s.string, data->main->warning.to, data->main->warning.notable, local->buffer, local->rule_objects.array[i], data->main->warning.notable);
-        fl_print_format("%[' is invalid.%]%r", data->main->warning.to, data->main->warning.context, data->main->warning.context, f_string_eol_s);
-
-        f_file_stream_unlock(data->main->warning.to);
-      }
-      else {
-        fll_print_format("%r%[%QAt line %ul, the object is missing.%]%r", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context, f_string_eol_s);
-      }
-
-      continue;
-    }
-
-    if (invalid) {
-      length = (local->rule_objects.array[i].stop - local->rule_objects.array[i].start) + 1;
-
-      if (length) {
-        f_file_stream_lock(data->main->warning.to);
-
-        fl_print_format("%r%[%QAt line %ul, the object '%]", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context);
-        fl_print_format(f_string_format_Q_range_single_s.string, data->main->warning.to, data->main->warning.notable, local->buffer, local->rule_objects.array[i], data->main->warning.notable);
-        fl_print_format("%[' has invalid content '%]", data->main->warning.to, data->main->warning.context, data->main->warning.context);
-        fl_print_format(f_string_format_Q_range_single_s.string, data->main->warning.to, data->main->warning.notable, local->buffer, local->rule_contents.array[i].array[0], data->main->warning.notable);
-        fl_print_format(f_string_format_sentence_end_quote_s.string, data->main->warning.to, data->main->warning.context, data->main->warning.context, f_string_eol_s);
-
-        f_file_stream_unlock(data->main->warning.to);
-      }
-      else {
-        fll_print_format("%r%[%QAt line %ul, the object has no content.%]%r", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context, f_string_eol_s);
-      }
-
-      continue;
-    }
-
-    for (r = repeat; F_status_is_error_not(status) && r; --r) {
-
-      arguments.used = 0;
-
-      // First add the program name.
-      status = f_memory_array_increase(F_memory_default_allocation_small_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-      if (F_status_is_error(status)) break;
-
-      if (tool == firewall_program_ip46tables_e) {
-        if (r == 2) {
-          current_tool = firewall_tool_iptables_s;
-        }
-        else {
-          current_tool = firewall_tool_ip6tables_s;
-        }
-      }
-
-      // Process the action when a non-none chain is specified.
-      if (chain != firewall_chain_none_id_e && action != firewall_action_none_id_e) {
-        status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-        if (F_status_is_error(status)) break;
-
-        arguments.array[arguments.used].used = 0;
-
-        if (action == firewall_action_append_id_e) {
-          status = f_string_dynamic_append(firewall_action_append_command_s, &arguments.array[arguments.used]);
-        }
-        else if (action == firewall_action_insert_id_e) {
-          status = f_string_dynamic_append(firewall_action_insert_command_s, &arguments.array[arguments.used]);
-        }
-        else if (action == firewall_action_policy_id_e) {
-          status = f_string_dynamic_append(firewall_action_policy_command_s, &arguments.array[arguments.used]);
-        }
-
-        if (F_status_is_error(status)) break;
-
-        if (action == firewall_action_append_id_e || action == firewall_action_insert_id_e || action == firewall_action_policy_id_e) {
-          ++arguments.used;
-
-          status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-          if (F_status_is_error(status)) break;
-
-          arguments.array[arguments.used].used = 0;
-          status = F_data_not;
-
-          // Process the chain, which is required by the action.
-          if (chain == firewall_chain_custom_id_e) {
-            status = f_string_dynamic_append(data->chains.array[local->chain_ids.array[local->chain]], &arguments.array[arguments.used]);
-          }
-          else if (chain == firewall_chain_forward_id_e) {
-            status = f_string_dynamic_append(firewall_chain_forward_s, &arguments.array[arguments.used]);
-          }
-          else if (chain == firewall_chain_postrouting_id_e) {
-            status = f_string_dynamic_append(firewall_chain_postrouting_s, &arguments.array[arguments.used]);
-          }
-          else if (chain == firewall_chain_prerouting_id_e) {
-            status = f_string_dynamic_append(firewall_chain_prerouting_s, &arguments.array[arguments.used]);
-          }
-          else if (chain == firewall_chain_input_id_e) {
-            status = f_string_dynamic_append(firewall_chain_input_s, &arguments.array[arguments.used]);
-          }
-          else if (chain == firewall_chain_output_id_e) {
-            status = f_string_dynamic_append(firewall_chain_output_s, &arguments.array[arguments.used]);
-          }
-
-          if (F_status_is_error(status)) break;
-
-          if (status == F_data_not) {
-            status = F_okay;
-          }
-          else {
-            ++arguments.used;
-          }
-        }
-      }
-
-      // Add the device if and only if a non-none direction is specified.
-      if (device.used && (direction == firewall_direction_input_id_e || direction == firewall_direction_output_id_e)) {
-        if (f_compare_dynamic_string(local->buffer.string + local->rule_contents.array[i].array[0].start, firewall_device_all_s, length) == F_equal_to_not) {
-
-          status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-          if (F_status_is_error(status)) break;
-
-          arguments.array[arguments.used].used = 0;
-
-          if (direction == firewall_direction_input_id_e) {
-            status = f_string_dynamic_append(firewall_device_input_command_s, &arguments.array[arguments.used]);
-
-            if (F_status_is_error(status)) break;
-
-            ++arguments.used;
-          }
-          else if (direction == firewall_direction_output_id_e) {
-            status = f_string_dynamic_append(firewall_device_output_command_s, &arguments.array[arguments.used]);
-
-            if (F_status_is_error(status)) break;
-
-            ++arguments.used;
-          }
-        }
-
-        // Add the device.
-        if (device.used) {
-          status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-          if (F_status_is_error(status)) break;
-
-          arguments.array[arguments.used].used = 0;
-
-          status = f_string_dynamic_append(device, &arguments.array[arguments.used]);
-
-          if (F_status_is_error(status)) break;
-
-          ++arguments.used;
-        }
-      }
-
-      if (use_protocol) {
-        status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-        if (F_status_is_error(status)) break;
-
-        arguments.array[arguments.used].used = 0;
-
-        status = f_string_dynamic_append(firewall_protocol_command_s, &arguments.array[arguments.used]);
-
-        if (F_status_is_error(status)) break;
-
-        ++arguments.used;
-
-        if (protocol.used) {
-          status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-          if (F_status_is_error(status)) break;
-
-          arguments.array[arguments.used].used = 0;
-
-          status = f_string_dynamic_append(protocol, &arguments.array[arguments.used]);
-
-          if (F_status_is_error(status)) break;
-
-          ++arguments.used;
-        }
-      }
-
-      // Last up is the "rule".
-      if ((!is_ip_list && local->rule_contents.array[i].used > 0) || (is_ip_list && local->rule_contents.array[i].used > 1)) {
-        f_number_unsigned_t subcounter = 0;
-
-        if (is_ip_list) {
-
-          // Skip past the chain.
-          ++subcounter;
-
-          length = (local->rule_contents.array[i].array[subcounter].stop - local->rule_contents.array[i].array[subcounter].start) + 1;
-
-          if (length) {
-            ip_list.used = 0;
-
-            status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[subcounter], &ip_list);
-
-            if (F_status_is_error(status)) {
-
-              // Prevent the loop below from being processed.
-              subcounter = local->rule_contents.array[i].used;
-            }
-            else {
-              ++subcounter;
-            }
-          }
-        }
-
-        status = f_memory_array_increase_by(local->rule_contents.array[i].used, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-        if (F_status_is_error(status)) break;
-
-        for (; subcounter < local->rule_contents.array[i].used; ++subcounter) {
-
-          length = (local->rule_contents.array[i].array[subcounter].stop - local->rule_contents.array[i].array[subcounter].start) + 1;
-
-          if (length) {
-            arguments.array[arguments.used].used = 0;
-
-            status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[subcounter], &arguments.array[arguments.used]);
-            if (F_status_is_error(status)) break;
-
-            ++arguments.used;
-          }
-        } // for
-      }
-      else {
-        length = (local->rule_objects.array[i].stop - local->rule_objects.array[i].start) + 1;
-
-        f_file_stream_lock(data->main->warning.to);
-
-        fl_print_format("%r%[%QAt line %ul, the object '%]", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, i, data->main->warning.context);
-        fl_print_format(f_string_format_Q_range_single_s.string, data->main->warning.to, data->main->warning.notable, local->buffer, local->rule_objects.array[i], data->main->warning.notable);
-        fl_print_format("%]%[' has no content.%]%r", data->main->warning.to, data->main->warning.context, data->main->warning.context, f_string_eol_s);
-
-        f_file_stream_unlock(data->main->warning.to);
-
-        break;
-      }
-
-      // Now execute the generated commands.
-      if (arguments.used > 1) {
-        if (is_ip_list) {
-          f_file_t file = f_file_t_initialize;
-          f_string_dynamic_t path_file = f_string_dynamic_t_initialize;
-          f_string_dynamic_t local_buffer = f_string_dynamic_t_initialize;
-
-          f_ranges_t basic_objects = f_ranges_t_initialize;
-          f_rangess_t basic_contents = f_ranges_t_initialize;
-
-          status = f_string_dynamic_append(firewall_network_path_s, &path_file);
-
-          if (F_status_is_error_not(status)) {
-            status = f_string_dynamic_append(ip_list, &path_file);
-          }
-
-          if (F_status_is_error_not(status)) {
-            status = f_file_open(path_file, 0, &file);
-          }
-
-          if (F_status_is_error(status)) {
-            if (F_status_set_fine(status) == F_parameter) {
-              if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
-                firewall_print_error_on_invalid_parameter(data->main->error, "f_file_open");
-              }
-            }
-            else if (F_status_set_fine(status) == F_file_found_not) {
-
-              // The file does not have to exist
-              if (data->main->error.verbosity != f_console_verbosity_verbose_e || data->main->error.verbosity == f_console_verbosity_debug_e) {
-                fll_print_format("%r%[%QCannot find the file '%Q'.%]%r", data->main->warning.to, f_string_eol_s, data->main->warning.context, data->main->warning.prefix, path_file, data->main->warning.context, f_string_eol_s);
-              }
-
-              status = F_okay;
-            }
-            else if (F_status_set_fine(status) == F_file_open) {
-              if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
-                fll_print_format("%r%[%QUnable to open the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
-              }
-            }
-            else if (F_status_set_fine(status) == F_file_descriptor) {
-              if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
-                fll_print_format("%r%[%QFile descriptor error while trying to open the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
-              }
-            }
-            else if (F_status_set_fine(status) == F_memory_not) {
-              firewall_print_error_on_allocation_failure(data->main->error);
-            }
-            else {
-              firewall_print_error_on_unhandled(data->main->error, "f_file_open", F_status_set_fine(status));
-            }
-
-            f_file_stream_flush(file);
-            f_file_stream_close(&file);
-          }
-          else {
-            status = f_file_read(file, &local_buffer);
-
-            f_file_stream_flush(file);
-            f_file_stream_close(&file);
-
-            if (F_status_is_error(status)) {
-              if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
-                if (F_status_set_fine(status) == F_parameter) {
-                  firewall_print_error_on_invalid_parameter(data->main->error, "f_file_read");
-                }
-                else if (F_status_set_fine(status) == F_number_overflow) {
-                  fll_print_format("%r%[%QInteger overflow while trying to buffer the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
-                }
-                else if (F_status_set_fine(status) == F_file_closed) {
-                  fll_print_format("%r%[%QThe file '%Q' is no longer open.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
-                }
-                else if (F_status_set_fine(status) == F_file_seek) {
-                  fll_print_format("%r%[%QA seek error occurred while accessing the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
-                }
-                else if (F_status_set_fine(status) == F_file_read) {
-                  fll_print_format("%r%[%QA read error occurred while accessing the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, path_file, data->main->error.context, f_string_eol_s);
-                }
-                else if (F_status_set_fine(status) != F_memory_not) {
-                  firewall_print_error_on_unhandled(data->main->error, "f_file_read", F_status_set_fine(status));
-                }
-              }
-            }
-            else {
-              f_number_unsigneds_t delimits = f_number_unsigneds_t_initialize;
-
-              {
-                f_state_t state = f_state_t_initialize;
-                f_range_t input = macro_f_range_t_initialize_2(local_buffer.used);
-
-                status = fll_fss_basic_read(local_buffer, state, &input, &basic_objects, &basic_contents, 0, &delimits, 0);
-              }
-
-              if (F_status_set_error(status)) {
-                status = F_status_set_fine(status);
-
-                if (status == F_parameter) {
-                  firewall_print_error_on_invalid_parameter_for_file(data->main->error, "fll_fss_basic_read", path_file.used ? path_file : f_string_empty_s);
-                }
-                else if (status == F_data_not_eos || status == F_data_not || status == F_data_not_stop) {
-                  // Empty files are to be silently ignored.
-                }
-                else if (status != F_memory_not) {
-                  firewall_print_error_on_unhandled_for_file(data->main->error, "fll_fss_basic_read", status, path_file.used ? path_file : f_string_empty_s);
-                }
-
-                status = F_status_set_error(status);
-              }
-
-              if (F_status_is_error_not(status)) {
-                f_state_t state = f_state_t_initialize;
-
-                status = f_fss_apply_delimit(state, delimits, &local_buffer);
-
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->main->error, F_status_set_fine(status), "f_fss_apply_delimit", fll_error_file_flag_fallback_e);
-                }
-              }
-
-              if (F_status_is_error_not(status)) {
-                status = f_memory_array_increase_by(2, sizeof(f_string_dynamic_t), (void **) &arguments.array, &arguments.used, &arguments.size);
-
-                if (F_status_is_error_not(status)) {
-                  arguments.array[arguments.used].used = 0;
-
-                  if (ip_list_direction) {
-                    status = f_string_dynamic_append(firewall_ip_list_destination_action_s, &arguments.array[arguments.used]);
-                  }
-                  else {
-                    status = f_string_dynamic_append(firewall_ip_list_source_action_s, &arguments.array[arguments.used]);
-                  }
-                }
-
-                if (F_status_is_error(status)) {
-                  f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
-
-                  break;
-                }
-
-                ++arguments.used;
-
-                // The ip_list file contains objects and no content, all objects are what matter an nothing else.
-                for (f_number_unsigned_t at = 0; at < basic_objects.used; ++at) {
-
-                  arguments.array[arguments.used].used = 0;
-
-                  status = f_string_dynamic_partial_append(local_buffer, basic_objects.array[at], &arguments.array[arguments.used]);
-                  if (F_status_is_error(status)) break;
-
-                  ++arguments.used;
-
-                  firewall_print_debug_tool(data->main->warning, current_tool, arguments);
-
-                  status = fll_execute_program(current_tool, arguments, 0, 0, (void *) &return_code);
-
-                  if (status == F_child) {
-                    f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
-                    f_memory_array_resize(0, sizeof(f_char_t), (void **) &ip_list.string, &ip_list.used, &ip_list.size);
-                    f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
-                    f_memory_array_resize(0, sizeof(f_char_t), (void **) &protocol.string, &protocol.used, &protocol.size);
-
-                    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
-
-                    data->main->child = return_code;
-
-                    return status;
-                  }
-
-                  // Remove ip_argument from arguments string.
-                  --arguments.used;
-
-                  if (F_status_is_error(status)) {
-                    if (F_status_set_fine(status) == F_failure) {
-                      firewall_print_error_on_operation(data->main->error, current_tool, arguments);
-                    }
-                    else if (F_status_set_fine(status) == F_parameter) {
-                      firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
-                    }
-                    else {
-                      firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
-                    }
-
-                    break;
-                  }
-                } // for
-
-                // Remove ip_list_action from arguments string.
-                --arguments.used;
-              }
-
-              f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
-            }
-          }
-
-          f_memory_array_resize(0, sizeof(f_char_t), (void **) &local_buffer.string, &local_buffer.used, &local_buffer.size);
-          f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
-
-          f_memory_array_resize(0, sizeof(f_range_t), (void **) &basic_objects.array, &basic_objects.used, &basic_objects.size);
-          f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &basic_contents.array, &basic_contents.used, &basic_contents.size, &f_rangess_delete_callback);
-
-          if (F_status_set_fine(status) == F_failure || F_status_set_fine(status) == F_parameter) break;
-        }
-        else {
-          firewall_print_debug_tool(data->main->warning, current_tool, arguments);
-
-          status = fll_execute_program(current_tool, arguments, 0, 0, (void *) &return_code);
-
-          if (status == F_child) {
-            f_memory_array_resize(0, sizeof(f_char_t), (void **) &ip_list.string, &ip_list.used, &ip_list.size);
-            f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
-            f_memory_array_resize(0, sizeof(f_char_t), (void **) &protocol.string, &protocol.used, &protocol.size);
-
-            f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
-
-            data->main->child = return_code;
-
-            return status;
-          }
-
-          if (F_status_is_error(status)) {
-            if (F_status_set_fine(status) == F_failure) {
-              firewall_print_error_on_operation(data->main->error, current_tool, arguments);
-            }
-            else if (F_status_set_fine(status) == F_parameter) {
-              firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
-            }
-            else if (F_status_set_fine(status) != F_memory_not) {
-              firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
-            }
-
-            break;
-          }
-        }
-      }
-    } // for
-  } // for
-
-  if (F_status_is_error(status)) {
-    if (F_status_set_fine(status) == F_memory_not) {
-      firewall_print_error_on_allocation_failure(data->main->error);
-    }
-  }
-
-  f_memory_array_resize(0, sizeof(f_char_t), (void **) &ip_list.string, &ip_list.used, &ip_list.size);
-  f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
-  f_memory_array_resize(0, sizeof(f_char_t), (void **) &protocol.string, &protocol.used, &protocol.size);
-
-  f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
-
-  return status;
-}
-
-f_status_t firewall_create_custom_chains(firewall_data_t * const data, firewall_reserved_chains_t * const reserved, firewall_local_data_t * const local) {
-
-  if (!data || !local) return F_status_set_error(F_parameter);
-
-  f_status_t status = F_okay;
-
-  uint8_t tool = firewall_program_iptables_e;
-  bool new_chain = F_false;
-  bool create_chain = F_false;
-  int return_code = 0;
-
-  f_number_unsigned_t i = 0;
-  f_number_unsigned_t j = 0;
-
-  f_number_unsigned_t length = 0;
-  f_string_dynamics_t arguments = f_string_dynamics_t_initialize;
-
-  local->chain_ids.used = local->chain_objects.used;
-
-  status = f_memory_arrays_resize(2, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
-  if (F_status_is_error(status)) return status;
-
-  status = f_memory_array_increase_by(local->chain_objects.used, sizeof(f_number_unsigned_t), (void **) &local->chain_ids.array, &local->chain_ids.used, &local->chain_ids.size);
-  if (F_status_is_error(status)) return status;
-
-  memset(local->chain_ids.array, 0, sizeof(f_number_unsigned_t) * local->chain_ids.used);
-
-  status = f_string_dynamic_append(firewall_chain_create_command_s, &arguments.array[0]);
-
-  if (F_status_is_error_not(status)) {
-    status = f_memory_array_increase(F_memory_default_allocation_small_d, sizeof(f_char_t), (void **) &arguments.array[1].string, &arguments.array[1].used, &arguments.array[1].size);
-  }
-  else {
-    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
-
-    return status;
-  }
-
-  arguments.used = 2;
-
-  reserved->has_lock = F_false;
-  reserved->has_stop = F_false;
-  reserved->has_main = F_false;
-
-  for (; i < local->chain_objects.used; ++i) {
-
-    new_chain = F_true;
-    j = 0;
-
-    if (!((++data->main->signal_check) % firewall_signal_check_d)) {
-      if (firewall_signal_received(data)) break;
-    }
-
-    // Skip globally reserved chain name: main.
-    if (f_compare_dynamic_partial_string(firewall_group_main_s.string, local->buffer, firewall_group_main_s.used, local->chain_objects.array[i]) == F_equal_to) {
-      new_chain = F_false;
-      reserved->has_main = F_true;
-      reserved->main_at = i;
-    }
-
-    // Skip globally reserved chain name: stop.
-    if (f_compare_dynamic_partial_string(firewall_group_stop_s.string, local->buffer, firewall_group_stop_s.used, local->chain_objects.array[i]) == F_equal_to) {
-      new_chain = F_false;
-      reserved->has_stop = F_true;
-      reserved->stop_at = i;
-    }
-
-    // Skip globally reserved chain name: lock.
-    if (f_compare_dynamic_partial_string(firewall_group_lock_s.string, local->buffer, firewall_group_lock_s.used, local->chain_objects.array[i]) == F_equal_to) {
-      new_chain = F_false;
-      reserved->has_lock = F_true;
-      reserved->lock_at = i;
-    }
-
-    // Skip globally reserved chain name: none.
-    if (f_compare_dynamic_partial_string(firewall_chain_none_s.string, local->buffer, firewall_chain_none_s.used, local->chain_objects.array[i]) == F_equal_to) {
-      new_chain = F_false;
-    }
-
-    if (new_chain) {
-      for (; j < data->chains.used; ++j) {
-
-        if (f_compare_dynamic_partial_string(data->chains.array[j].string, local->buffer, data->chains.array[j].used, local->chain_objects.array[i]) == F_equal_to) {
-          new_chain = F_false;
-          local->chain_ids.array[i] = j;
-
-          break;
-        }
-      } // for
-    }
-
-    if (new_chain) {
-      status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &data->chains.array, &data->chains.used, &data->chains.size);
-      if (F_status_is_error(status)) break;
-
-      create_chain = F_true;
-      length = (local->chain_objects.array[i].stop - local->chain_objects.array[i].start) + 1;
-
-      arguments.array[1].used = 0;
-
-      status = f_memory_array_increase_by(length + 1, sizeof(f_char_t), (void **) &arguments.array[1].string, &arguments.array[1].used, &arguments.array[1].size);
-      if (F_status_is_error(status)) break;
-
-      status = f_memory_array_increase_by(length + 1, sizeof(f_char_t), (void **) &data->chains.array[data->chains.used].string, &data->chains.array[data->chains.used].used, &data->chains.array[data->chains.used].size);
-      if (F_status_is_error(status)) break;
-
-      data->chains.array[data->chains.used].used = 0;
-      local->chain_ids.array[i] = data->chains.used;
-
-      // Copy the string character by character, ignoring placeholders.
-      for (j = local->chain_objects.array[i].start; j <= local->chain_objects.array[i].stop; ++j) {
-
-        if (local->buffer.string[j] == f_fss_placeholder_s.string[0]) continue;
-
-        data->chains.array[data->chains.used].string[data->chains.array[data->chains.used].used++] = local->buffer.string[j];
-        arguments.array[1].string[arguments.array[1].used++] = local->buffer.string[j];
-      } // for
-
-      arguments.array[1].string[arguments.array[1].used] = 0;
-      data->chains.array[data->chains.used].string[data->chains.array[data->chains.used].used] = 0;
-
-      if (f_compare_dynamic(arguments.array[1], firewall_chain_forward_s) == F_equal_to) {
-        create_chain = F_false;
-      }
-      else if (f_compare_dynamic(arguments.array[1], firewall_chain_input_s) == F_equal_to) {
-        create_chain = F_false;
-      }
-      else if (f_compare_dynamic(arguments.array[1], firewall_chain_output_s) == F_equal_to) {
-        create_chain = F_false;
-      }
-      else if (f_compare_dynamic(arguments.array[1], firewall_chain_postrouting_s) == F_equal_to) {
-        create_chain = F_false;
-      }
-      else if (f_compare_dynamic(arguments.array[1], firewall_chain_prerouting_s) == F_equal_to) {
-        create_chain = F_false;
-      }
-
-      if (create_chain) {
-        firewall_print_debug_tool(data->main->warning, firewall_tool_iptables_s, arguments);
-
-        tool = firewall_program_iptables_e;
-        status = fll_execute_program(firewall_tool_iptables_s, arguments, 0, 0, (void *) &return_code);
-
-        if (status == F_child) {
-          data->main->child = return_code;
-
-          break;
-        }
-
-        if (F_status_is_error_not(status)) {
-          if (firewall_signal_received(data)) {
-            status = F_status_set_error(F_interrupt);
-
-            break;
-          }
-
-          firewall_print_debug_tool(data->main->warning, firewall_tool_ip6tables_s, arguments);
-
-          tool = firewall_program_ip6tables_e;
-          status = fll_execute_program(firewall_tool_ip6tables_s, arguments, 0, 0, (void *) &return_code);
-
-          if (status == F_child) {
-            data->main->child = return_code;
-
-            break;
-          }
-        }
-
-        if (F_status_is_error(status)) {
-          if (F_status_set_fine(status) == F_failure) {
-            firewall_print_error_on_operation(data->main->error, tool == firewall_program_iptables_e ? firewall_tool_iptables_s : firewall_tool_ip6tables_s, arguments);
-          }
-          else if (F_status_set_fine(status) == F_parameter) {
-            firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
-          }
-          else {
-            firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
-          }
-
-          break;
-        }
-      }
-
-      ++data->chains.used;
-    }
-  } // for
-
-  f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
-
-  return status;
-}
-
-f_status_t firewall_delete_chains(firewall_data_t * const data) {
-
-  if (!data) return F_status_set_error(F_parameter);
-
-  const f_string_static_t tools[2] = { firewall_tool_iptables_s, firewall_tool_ip6tables_s };
-  f_status_t status = F_okay;
-
-  for (f_number_unsigned_t i = 0; i < 2; ++i) {
-
-    if (firewall_signal_received(data)) {
-      return F_status_set_error(F_interrupt);
-    }
-
-    f_string_statics_t arguments = f_string_statics_t_initialize;
-    arguments.used = 1;
-
-    f_string_static_t arguments_array[arguments.used];
-    arguments_array[0] = firewall_chain_flush_command_s;
-    arguments.array = arguments_array;
-
-    int return_code = 0;
-
-    firewall_print_debug_tool(data->main->warning, tools[i], arguments);
-
-    status = fll_execute_program(tools[i], arguments, 0, 0, (void *) &return_code);
-
-    if (status == F_child) {
-      data->main->child = return_code;
-
-      return status;
-    }
-
-    if (F_status_is_error(status)) {
-      if (F_status_set_fine(status) == F_failure) {
-        firewall_print_error_on_operation(data->main->error, tools[i], arguments);
-      }
-      else if (F_status_set_fine(status) == F_parameter) {
-        firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
-      }
-      else {
-        firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
-      }
-
-      return status;
-    }
-  } // for
-
-  int return_code = 0;
-
-  f_string_statics_t arguments = f_string_statics_t_initialize;
-  arguments.used = 1;
-
-  f_string_static_t argument_array[arguments.used];
-  arguments.array = argument_array;
-  argument_array[0] = firewall_chain_delete_command_s;
-
-  for (f_number_unsigned_t i = 0; i < 2; ++i) {
-
-    firewall_print_debug_tool(data->main->warning, tools[i], arguments);
-
-    return_code = 0;
-
-    status = fll_execute_program(tools[i], arguments, 0, 0, (void *) &return_code);
-
-    if (status == F_child) {
-      data->main->child = return_code;
-
-      break;
-    }
-
-    if (firewall_signal_received(data)) {
-      status = F_status_set_error(F_interrupt);
-
-      break;
-    }
-
-    if (F_status_is_error(status)) {
-      if (F_status_set_fine(status) == F_failure) {
-        firewall_print_error_on_operation(data->main->error, tools[i], arguments);
-      }
-      else if (F_status_set_fine(status) == F_parameter) {
-        firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
-      }
-      else {
-        firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
-      }
-
-      break;
-    }
-  } // for
-
-  return status;
-}
-
-f_status_t firewall_default_lock(firewall_data_t * const data) {
-
-  if (!data) return F_status_set_error(F_parameter);
-
-  const f_string_static_t chains[3] = { firewall_chain_input_s, firewall_chain_output_s, firewall_chain_forward_s };
-  const f_string_static_t tools[2] = { firewall_tool_iptables_s, firewall_tool_ip6tables_s };
-
-  f_status_t status = F_okay;
-
-  int return_code = 0;
-
-  f_string_statics_t arguments = f_string_statics_t_initialize;
-  arguments.used = 3;
-
-  f_string_static_t argument_array[arguments.used];
-  arguments.array = argument_array;
-  arguments.array[0] = firewall_action_policy_command_s;
-  arguments.array[2] = firewall_chain_drop_s;
-
-  f_number_unsigned_t i = 0;
-  f_number_unsigned_t j = 0;
-
-  for (; i < 3; ++i) {
-
-    arguments.array[1] = chains[i];
-
-    for (j = 0; j < 2; ++j) {
-
-      firewall_print_debug_tool(data->main->warning, tools[j], arguments);
-
-      return_code = 0;
-
-      status = fll_execute_program(tools[j], arguments, 0, 0, (void *) &return_code);
-
-      if (status == F_child) {
-        data->main->child = return_code;
-
-        break;
-      }
-
-      if (firewall_signal_received(data)) {
-        status = F_status_set_error(F_interrupt);
-
-        break;
-      }
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_failure) {
-          firewall_print_error_on_operation(data->main->error, tools[j], arguments);
-        }
-        else if (F_status_set_fine(status) == F_parameter) {
-          firewall_print_error_on_invalid_parameter(data->main->error, "fll_execute_program");
-        }
-        else {
-          firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
-        }
-
-        break;
-      }
-    } // for
-  } // for
-
-  return status;
-}
-
-f_status_t firewall_buffer_rules(firewall_data_t * const data, const f_string_static_t filename, const bool optional, firewall_local_data_t * const local) {
-
-  if (!data || !local) return F_status_set_error(F_parameter);
-
-  f_file_t file = f_file_t_initialize;
-
-  f_status_t status = f_file_open(filename, 0, &file);
-
-  if (F_status_is_error(status)) {
-    if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
-      if (optional) {
-        if (F_status_set_fine(status) == F_parameter) {
-          firewall_print_error_on_invalid_parameter(data->main->error, "f_file_open");
-        }
-        else if (F_status_set_fine(status) != F_file_found_not && F_status_set_fine(status) != F_file_open && F_status_set_fine(status) != F_file_descriptor) {
-          firewall_print_error_on_unhandled(data->main->error, "f_file_open", F_status_set_fine(status));
-        }
-      } else {
-        if (F_status_set_fine(status) == F_parameter) {
-          firewall_print_error_on_invalid_parameter(data->main->error, "f_file_open");
-        }
-        else if (F_status_set_fine(status) == F_file_found_not) {
-          fll_print_format("%r%[%QUnable to find the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
-        }
-        else if (F_status_set_fine(status) == F_file_open) {
-          fll_print_format("%r%[%QUnable to open the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
-        }
-        else if (F_status_set_fine(status) == F_file_descriptor) {
-          fll_print_format("%r%[%QFile descriptor error while trying to open the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
-        }
-        else {
-          firewall_print_error_on_unhandled(data->main->error, "f_file_open", F_status_set_fine(status));
-        }
-      }
-    }
-
-    return status;
-  }
-
-  status = f_file_read(file, &local->buffer);
-
-  f_file_stream_flush(file);
-  f_file_stream_close(&file);
-
-  if (F_status_is_error(status)) {
-    if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
-      if (F_status_set_fine(status) == F_parameter) {
-        firewall_print_error_on_invalid_parameter(data->main->error, "f_file_read");
-      }
-      else if (F_status_set_fine(status) == F_number_overflow) {
-        fll_print_format("%r%[%QInteger overflow while trying to buffer the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
-      }
-      else if (F_status_set_fine(status) == F_file_closed) {
-        fll_print_format("%r%[%QThe file '%Q' is no longer open.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
-      }
-      else if (F_status_set_fine(status) == F_file_seek) {
-        fll_print_format("%r%[%QA seek error occurred while accessing the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
-      }
-      else if (F_status_set_fine(status) == F_file_read) {
-        fll_print_format("%r%[%QA read error occurred while accessing the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
-      }
-      else if (F_status_set_fine(status) == F_memory_not) {
-        firewall_print_error_on_allocation_failure(data->main->error);
-      }
-      else {
-        firewall_print_error_on_unhandled(data->main->error, "f_file_read", F_status_set_fine(status));
-      }
-    }
-
-    return status;
-  }
-
-  f_number_unsigneds_t delimits = f_number_unsigneds_t_initialize;
-  f_range_t comments = f_range_t_initialize;
-  f_state_t state = f_state_t_initialize;
-
-  {
-    f_range_t input = macro_f_range_t_initialize_2(local->buffer.used);
-
-    status = fll_fss_basic_list_read(local->buffer, state, &input, &local->chain_objects, &local->chain_contents, &delimits, 0, &comments);
-  }
-
-  if (F_status_is_error(status)) {
-    status = F_status_set_fine(status);
-
-    if (data->main->error.verbosity > f_console_verbosity_quiet_e) {
-      if (status == F_parameter) {
-        firewall_print_error_on_invalid_parameter_for_file(data->main->error, "fll_fss_basic_list_read", filename);
-      }
-      else if (status == F_data_not_eos || status == F_data_not || status == F_data_not_stop) {
-        fll_print_format("%r%[%QNo relevant main was found within the file '%Q'.%]%r", data->main->error.to, f_string_eol_s, data->main->error.context, data->main->error.prefix, filename, data->main->error.context, f_string_eol_s);
-      }
-      else if (status == F_memory_not) {
-        firewall_print_error_on_allocation_failure(data->main->error);
-      }
-      else {
-        firewall_print_error_on_unhandled_for_file(data->main->error, "fll_fss_basic_read", status, filename);
-      }
-    }
-  }
-  else {
-    status = f_fss_apply_delimit(state, delimits, &local->buffer);
-
-    if (F_status_is_error(status)) {
-      fll_error_print(data->main->error, F_status_set_fine(status), "f_fss_apply_delimit", fll_error_file_flag_fallback_e);
-    }
-  }
-
-  f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
-  macro_f_range_t_delete_simple(comments);
-
-  return status;
-}
-
-f_status_t firewall_process_rules(firewall_data_t * const data, f_range_t * const range, firewall_local_data_t * const local) {
-
-  if (!data || !range || !local) return F_status_set_error(F_parameter);
-
-  f_status_t status = F_okay;
-  f_number_unsigneds_t delimits = f_number_unsigneds_t_initialize;
-  f_state_t state = f_state_t_initialize;
-
-  status = fll_fss_extended_read(local->buffer, state, range, &local->rule_objects, &local->rule_contents, 0, 0, &delimits, 0);
-
-  if (F_status_is_error_not(status)) {
-    status = f_fss_apply_delimit(state, delimits, &local->buffer);
-
-    if (F_status_is_error(status)) {
-      fll_error_print(data->main->error, F_status_set_fine(status), "f_fss_apply_delimit", fll_error_file_flag_fallback_e);
-    }
-  }
-
-  f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
-
-  if (F_status_is_error_not(status)) {
-    status = firewall_perform_commands(data, local);
-
-    if (F_status_is_error(status)) {
-      if (F_status_set_fine(status) == F_memory_not) {
-        firewall_print_error_on_allocation_failure(data->main->error);
-      }
-      else if (F_status_set_fine(status) == F_failure) {
-        // The error message has already been displayed.
-      }
-      else {
-        firewall_print_error_on_unhandled(data->main->error, "firewall_perform_commands", F_status_set_fine(status));
-      }
-    }
-  }
-
-  f_memory_array_resize(0, sizeof(f_range_t), (void **) &local->rule_objects.array, &local->rule_objects.used, &local->rule_objects.size);
-  f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &local->rule_contents.array, &local->rule_contents.used, &local->rule_contents.size, &f_rangess_delete_callback);
-
-  return status;
-}
-
-f_status_t firewall_delete_local_data(firewall_local_data_t * const local) {
-
-  if (!local) return F_status_set_error(F_parameter);
-
-  local->is_global = F_true;
-  local->is_main = F_false;
-  local->is_stop = F_false;
-  local->is_lock = F_false;
-
-  local->device = 0;
-  local->chain = 0;
-
-  f_memory_array_resize(0, sizeof(f_char_t), (void **) &local->buffer.string, &local->buffer.used, &local->buffer.size);
-  f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &local->chain_ids.array, &local->chain_ids.used, &local->chain_ids.size);
-
-  f_memory_array_resize(0, sizeof(f_range_t), (void **) &local->chain_objects.array, &local->chain_objects.used, &local->chain_objects.size);
-  f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &local->chain_contents.array, &local->chain_contents.used, &local->chain_contents.size, &f_rangess_delete_callback);
-
-  f_memory_array_resize(0, sizeof(f_range_t), (void **) &local->rule_objects.array, &local->rule_objects.used, &local->rule_objects.size);
-  f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &local->rule_contents.array, &local->rule_contents.used, &local->rule_contents.size, &f_rangess_delete_callback);
-
-  return F_okay;
-}
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/level_3/firewall/c/private-firewall.h b/level_3/firewall/c/private-firewall.h
deleted file mode 100644 (file)
index 76ce290..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * FLL - Level 3
- *
- * Project: Firewall
- * API Version: 0.7
- * Licenses: lgpl-2.1-or-later
- */
-#ifndef _PRIVATE_firewall_h
-#define _PRIVATE_firewall_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Perform commands.
- *
- * @param data
- *   The program data.
- * @param local
- *   Local firewall settings.
- *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
- *
- *   F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal.
- *   F_parameter (with error bit) on invalid parameter passed.
- *
- *   Errors (with error bit) from: f_memory_array_increase().
- *   Errors (with error bit) from: f_memory_array_increase_by().
- *   Errors (with error bit) from: f_string_dynamic_append().
- *   Errors (with error bit) from: f_string_dynamic_partial_append().
- *
- * @see f_memory_array_increase()
- * @see f_memory_array_increase_by()
- * @see f_string_dynamic_append()
- * @see f_string_dynamic_partial_append()
- */
-extern f_status_t firewall_perform_commands(firewall_data_t * const data, firewall_local_data_t * const local) F_attribute_visibility_internal_d;
-
-/**
- * Create custom chains.
- *
- * @param data
- *   The program data.
- * @param reserved
- *   firewall chains.
- * @param local
- *   Local firewall settings.
- *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
- *
- *   F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal.
- *   F_parameter (with error bit) on invalid parameter passed.
- *
- *   Status codes (with error bit) are returned on any problem.
- */
-extern f_status_t firewall_create_custom_chains(firewall_data_t * const data, firewall_reserved_chains_t * const reserved, firewall_local_data_t * const local) F_attribute_visibility_internal_d;
-
-/**
- * Deallocate chains.
- *
- * @param data
- *   The program data.
- *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
- *
- *   F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal.
- *   F_parameter (with error bit) on invalid parameter passed.
- *
- *   Status codes (with error bit) are returned on any problem.
- */
-extern f_status_t firewall_delete_chains(firewall_data_t * const data) F_attribute_visibility_internal_d;
-
-/**
- * Lock the firewall.
- *
- * @param data
- *   The program data.
- *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
- *
- *   Status codes (with error bit) are returned on any problem.
- */
-extern f_status_t firewall_default_lock(firewall_data_t * const data) F_attribute_visibility_internal_d;
-
-/**
- * Buffer firewall rules.
- *
- * @param data
- *   The program data.
- * @param filename
- *   File name to read the rules from.
- * @param optional
- *   TRUE if this files is optional.
- *   FALSE otherwise (more are errors returned when not optional).
- * @param local
- *   Local firewall settings.
- *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
- *
- *   Status codes (with error bit) are returned on any problem.
- */
-extern f_status_t firewall_buffer_rules(firewall_data_t * const data, const f_string_static_t filename, const bool optional, firewall_local_data_t * const local) F_attribute_visibility_internal_d;
-
-/**
- * Process buffered rules.
- *
- * @param data
- *   The program data.
- * @param range
- *   The current position within the buffer and the stop point.
- * @param local
- *   Local firewall settings.
- *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
- *
- *   Status codes (with error bit) are returned on any problem.
- */
-extern f_status_t firewall_process_rules(firewall_data_t * const data, f_range_t * const range, firewall_local_data_t * const local) F_attribute_visibility_internal_d;
-
-/**
- * Delete allocated local data.
- *
- * @param local
- *   Local firewall settings.
- *
- * @return
- *   F_okay on success.
- *
- *   Status codes (with error bit) are returned on any problem.
- */
-extern f_status_t firewall_delete_local_data(firewall_local_data_t * const local) F_attribute_visibility_internal_d;
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // _PRIVATE_firewall_h
index 4404ee0..9721206 100644 (file)
@@ -20,39 +20,41 @@ extern "C" {
  * Flags passed to the main function or program.
  *
  * fss_identify_main_flag_*_e:
- *   - none:          No flags set.
- *   - content:       Use the content (The "0000" part of "FSS-0000").
- *   - copyright:     Print copyright.
- *   - file_from:     Using a specified source file.
- *   - file_to:       Using a specified destination file. (Not used at this time.)
- *   - header:        Enable printing of headers.
- *   - help:          Print help.
- *   - line:          Print only the identifier at a given line.
- *   - name:          Select using this full or partial type name or code.
- *   - object:        Use the object (The "FSS" part of "FSS-0000").
- *   - pipe:          Use the input pipe.
- *   - print_first:   When set, print new line to message output on program begin after loading settings.
- *   - print_last:    When set, print new line to message output on program end.
- *   - total:         Print the total Identifiers found.
- *   - version:       Print version.
+ *   - none:                   No flags set.
+ *   - content:                Use the content (The "0000" part of "FSS-0000").
+ *   - copyright:              Print copyright.
+ *   - file_from:              Using a specified source file.
+ *   - file_to:                Using a specified destination file. (Not used at this time.)
+ *   - header:                 Enable printing of headers.
+ *   - help:                   Print help.
+ *   - line:                   Print only the identifier at a given line.
+ *   - name:                   Select using this full or partial type name or code.
+ *   - object:                 Use the object (The "FSS" part of "FSS-0000").
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - total:                  Print the total Identifiers found.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
  */
 #ifndef _di_fss_identify_main_flag_e_
   enum {
-    fss_identify_main_flag_none_e          = 0x0,
-    fss_identify_main_flag_content_e       = 0x1,
-    fss_identify_main_flag_copyright_e     = 0x2,
-    fss_identify_main_flag_file_from_e     = 0x4,
-    fss_identify_main_flag_file_to_e       = 0x8,
-    fss_identify_main_flag_header_e        = 0x10,
-    fss_identify_main_flag_help_e          = 0x20,
-    fss_identify_main_flag_line_e          = 0x40,
-    fss_identify_main_flag_name_e          = 0x80,
-    fss_identify_main_flag_object_e        = 0x100,
-    fss_identify_main_flag_pipe_e          = 0x200,
-    fss_identify_main_flag_print_first_e   = 0x400,
-    fss_identify_main_flag_print_last_e    = 0x800,
-    fss_identify_main_flag_total_e         = 0x1000,
-    fss_identify_main_flag_version_e       = 0x2000,
+    fss_identify_main_flag_none_e                   = 0x0,
+    fss_identify_main_flag_content_e                = 0x1,
+    fss_identify_main_flag_copyright_e              = 0x2,
+    fss_identify_main_flag_file_from_e              = 0x4,
+    fss_identify_main_flag_file_to_e                = 0x8,
+    fss_identify_main_flag_header_e                 = 0x10,
+    fss_identify_main_flag_help_e                   = 0x20,
+    fss_identify_main_flag_line_e                   = 0x40,
+    fss_identify_main_flag_name_e                   = 0x80,
+    fss_identify_main_flag_object_e                 = 0x100,
+    fss_identify_main_flag_pipe_e                   = 0x200,
+    fss_identify_main_flag_print_first_e            = 0x400,
+    fss_identify_main_flag_print_last_e             = 0x800,
+    fss_identify_main_flag_total_e                  = 0x1000,
+    fss_identify_main_flag_version_e                = 0x2000,
+    fss_identify_main_flag_version_copyright_help_e = 0x2022,
   }; // enum
 #endif // _di_fss_identify_main_flag_e_
 
@@ -79,7 +81,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(fss_identify_short_total_s, fss_identify_long_total_s, 0, f_console_flag_normal_e), \
     }
 
-  #define fss_identify_parameter_total_d 18
+  #define fss_identify_parameter_total_d (f_console_parameter_state_type_total_d + 5)
 #endif // _di_fss_identify_parameter_e_
 
 /**
index dc49243..c15ad1d 100644 (file)
@@ -23,7 +23,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (fss_identify_main_flag_help_e | fss_identify_main_flag_version_e | fss_identify_main_flag_copyright_e)) {
+    if (main->setting.flag & fss_identify_main_flag_version_copyright_help_e) {
       if (main->setting.flag & fss_identify_main_flag_help_e) {
         fss_identify_print_message_help(&main->program.message);
       }
@@ -89,8 +89,7 @@ extern "C" {
       fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
     }
 
-    if (F_status_set_fine(main->setting.state.status) == F_interrupt) return;
-    if (F_status_is_error(main->setting.state.status)) return;
+    if (F_status_is_error(main->setting.state.status) || main->setting.state.status == F_interrupt) return;
 
     main->setting.state.status = F_okay;
   }
index 9e191b3..1805e94 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #ifndef _di_fss_identify_load_line_
   void fss_identify_load_line(fss_identify_main_t * const main, const f_string_static_t name) {
 
index fbbadc4..96d2366 100644 (file)
@@ -9,8 +9,8 @@
  *
  * This is auto-included and should not need to be explicitly included.
  */
-#ifndef _fss_identify_print_data_data_h
-#define _fss_identify_print_data_data_h
+#ifndef _fss_identify_print_data_h
+#define _fss_identify_print_data_h
 
 #ifdef __cplusplus
 extern "C" {
@@ -58,4 +58,4 @@ extern "C" {
 } // extern "C"
 #endif
 
-#endif // _fss_identify_print_data_data_h
+#endif // _fss_identify_print_data_h
index 8bfaeeb..537250d 100644 (file)
@@ -51,8 +51,8 @@ extern "C" {
     f_file_stream_lock(print->to);
 
     fl_print_format("%[%QEmpty string is not allowed at index%] ", print->to, print->set->error, print->prefix, print->set->error);
-    fl_print_format("%[%ul%] ", print->to, print->set->notable, index, print->set->notable);
-    fl_print_format("%[for the parameter '%]", print->to, print->set->error, print->set->error);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->set->notable, index, print->set->notable);
+    fl_print_format(" %[for the parameter '%]", print->to, print->set->error, print->set->error);
     fl_print_format(f_string_format_rr_single_s.string, print->to, print->set->notable, f_console_symbol_long_normal_s, fss_identify_long_name_s, print->set->notable);
     fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
 
@@ -73,8 +73,8 @@ extern "C" {
     fl_print_format("%[%QThe value '%]", print->to, print->set->error, print->prefix, print->set->error);
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
     fl_print_format("%[' at index%] ", print->to, print->set->error, print->set->error);
-    fl_print_format("%[%ul%] ", print->to, print->set->notable, index, print->set->notable);
-    fl_print_format("%[for the parameter '%]", print->to, print->set->error, print->set->error);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->set->notable, index, print->set->notable);
+    fl_print_format("%[ for the parameter '%]", print->to, print->set->error, print->set->error);
     fl_print_format(f_string_format_rr_single_s.string, print->to, print->set->notable, f_console_symbol_long_normal_s, fss_identify_long_name_s, print->set->notable);
     fl_print_format("%[' may only contain word characters or the dash (minus) character.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
 
index 594b181..3e2a64f 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
  *   The output structure to print to.
  *
  *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
  *
  * @return
  *   F_okay on success.
index fc998a7..8b64f5f 100644 (file)
@@ -5,7 +5,7 @@
  * API Version: 0.7
  * Licenses: lgpl-2.1-or-later
  *
- * Provides the print functionality.
+ * Provides the print message functionality.
  *
  * This is auto-included and should not need to be explicitly included.
  */
index 0dea440..eca32d6 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #ifndef _di_fss_identify_process_
   void fss_identify_process(fss_identify_main_t * const main, const f_string_static_t name) {
 
index 6196bd2..6f9c1c9 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_fss_identify_thread_signal_) && !defined(_di_thread_support_)
   void * fss_identify_thread_signal(void * const main) {
 
index 5bd7227..04d95ba 100644 (file)
@@ -20,75 +20,77 @@ extern "C" {
  * Flags passed to the main function or program.
  *
  * fss_read_main_flag_*_e:
- *   - none:              No flags set.
- *   - at:                The object at the given position is being selected (Think of this as select a row for some Object).
- *   - columns:           The total columns found and selected is printed instead of the Content.
- *   - content:           The Content is to be printed.
- *   - content_has_close: The Content has a closing character which needs to be counted and handled when processing both Object and Content, but is otherwise not processed or printed.
- *   - content_multiple:  Designate that multiple Content is allowed for an Object for this standard rather than a single Content per Object.
- *   - copyright:         Print copyright.
- *   - delimit:           How delimits are to be handled is designated.
- *   - depth:             The depth is specified at least once.
- *   - depth_multiple:    Designate that multiple depths are allowed within Content rather than being single depth Content.
- *   - empty:             Empty Content will be printed (Objects that have no Content will have their empty Content printed).
- *   - help:              Print help.
- *   - line:              A specific Content at a given line is to be selected (Think of this as select a row for some Content).
- *   - line_single:       Designate that only a single line for Content is allowed for an Object for this standard rather than allowing multiple lines per Content per Object.
- *   - name:              A specific Object name has been requested.
- *   - object:            The Object is to be printed.
- *   - object_as_line:    The Object is counted as its own line for the purpose of -l/--line or any other similar behavior.
- *   - object_trim:       Empty space before an after Objects are ignored while processing without affecting printing behavior.
- *   - original:          Enable original printing, where the quotes are printed and no delimits are applied.
- *   - payload_create:    Create the payload Object with empty Content if the payload Object is missing (when using FSS Payload and related).
- *   - payload_error:     Treat missing or invalid payload as an error (when using FSS Payload and related).
- *   - payload_warn:      Treat missing or invalid payload as a warning (when using FSS Payload and related).
- *   - pipe:              Use the input pipe.
- *   - pipe_format:       Print using the special pipe format.
- *   - print_first:       When set, print new line to message output on program begin after loading settings.
- *   - print_last:        When set, print new line to message output on program end.
- *   - quote_content:     Designate that the standard supports quotes on Content.
- *   - quote_object:      Designate that the standard supports quotes on Objects.
- *   - select:            A specific Content at a given position is to be selected (Think of this as select a column for some Content).
- *   - total:             The total lines found and selected is printed instead of the Content.
- *   - trim:              Empty space before and after Objects and Content will not be printed (They will be trimmed).
- *   - trim_object:       Empty space before and after Objects (but not Content) will not be printed (They will be trimmed).
- *   - version:           Print version.
+ *   - none:                   No flags set.
+ *   - at:                     The object at the given position is being selected (Think of this as select a row for some Object).
+ *   - columns:                The total columns found and selected is printed instead of the Content.
+ *   - content:                The Content is to be printed.
+ *   - content_has_close:      The Content has a closing character which needs to be counted and handled when processing both Object and Content, but is otherwise not processed or printed.
+ *   - content_multiple:       Designate that multiple Content is allowed for an Object for this standard rather than a single Content per Object.
+ *   - copyright:              Print copyright.
+ *   - delimit:                How delimits are to be handled is designated.
+ *   - depth:                  The depth is specified at least once.
+ *   - depth_multiple:         Designate that multiple depths are allowed within Content rather than being single depth Content.
+ *   - empty:                  Empty Content will be printed (Objects that have no Content will have their empty Content printed).
+ *   - help:                   Print help.
+ *   - line:                   A specific Content at a given line is to be selected (Think of this as select a row for some Content).
+ *   - line_single:            Designate that only a single line for Content is allowed for an Object for this standard rather than allowing multiple lines per Content per Object.
+ *   - name:                   A specific Object name has been requested.
+ *   - object:                 The Object is to be printed.
+ *   - object_as_line:         The Object is counted as its own line for the purpose of -l/--line or any other similar behavior.
+ *   - object_trim:            Empty space before an after Objects are ignored while processing without affecting printing behavior.
+ *   - original:               Enable original printing, where the quotes are printed and no delimits are applied.
+ *   - payload_create:         Create the payload Object with empty Content if the payload Object is missing (when using FSS Payload and related).
+ *   - payload_error:          Treat missing or invalid payload as an error (when using FSS Payload and related).
+ *   - payload_warn:           Treat missing or invalid payload as a warning (when using FSS Payload and related).
+ *   - pipe:                   Use the input pipe.
+ *   - pipe_format:            Print using the special pipe format.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - quote_content:          Designate that the standard supports quotes on Content.
+ *   - quote_object:           Designate that the standard supports quotes on Objects.
+ *   - select:                 A specific Content at a given position is to be selected (Think of this as select a column for some Content).
+ *   - total:                  The total lines found and selected is printed instead of the Content.
+ *   - trim:                   Empty space before and after Objects and Content will not be printed (They will be trimmed).
+ *   - trim_object:            Empty space before and after Objects (but not Content) will not be printed (They will be trimmed).
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
  */
 #ifndef _di_fss_read_main_flag_e_
   enum {
-    fss_read_main_flag_none_e              = 0x0,
-    fss_read_main_flag_at_e                = 0x1,
-    fss_read_main_flag_columns_e           = 0x2,
-    fss_read_main_flag_content_e           = 0x4,
-    fss_read_main_flag_content_has_close_e = 0x8,
-    fss_read_main_flag_content_multiple_e  = 0x10,
-    fss_read_main_flag_copyright_e         = 0x20,
-    fss_read_main_flag_delimit_e           = 0x40,
-    fss_read_main_flag_depth_e             = 0x80,
-    fss_read_main_flag_depth_multiple_e    = 0x100,
-    fss_read_main_flag_empty_e             = 0x200,
-    fss_read_main_flag_help_e              = 0x400,
-    fss_read_main_flag_line_e              = 0x800,
-    fss_read_main_flag_line_single_e       = 0x1000,
-    fss_read_main_flag_name_e              = 0x2000,
-    fss_read_main_flag_object_e            = 0x4000,
-    fss_read_main_flag_object_as_line_e    = 0x8000,
-    fss_read_main_flag_object_trim_e       = 0x10000,
-    fss_read_main_flag_original_e          = 0x20000,
-    fss_read_main_flag_payload_create_e    = 0x40000,
-    fss_read_main_flag_payload_error_e     = 0x80000,
-    fss_read_main_flag_payload_warn_e      = 0x100000,
-    fss_read_main_flag_pipe_e              = 0x200000,
-    fss_read_main_flag_pipe_format_e       = 0x400000,
-    fss_read_main_flag_print_first_e       = 0x800000,
-    fss_read_main_flag_print_last_e        = 0x1000000,
-    fss_read_main_flag_quote_content_e     = 0x2000000,
-    fss_read_main_flag_quote_object_e      = 0x4000000,
-    fss_read_main_flag_select_e            = 0x8000000,
-    fss_read_main_flag_total_e             = 0x10000000,
-    fss_read_main_flag_trim_e              = 0x20000000,
-    fss_read_main_flag_trim_object_e       = 0x40000000,
-    fss_read_main_flag_version_e           = 0x80000000,
+    fss_read_main_flag_none_e                   = 0x0,
+    fss_read_main_flag_at_e                     = 0x1,
+    fss_read_main_flag_columns_e                = 0x2,
+    fss_read_main_flag_content_e                = 0x4,
+    fss_read_main_flag_content_has_close_e      = 0x8,
+    fss_read_main_flag_content_multiple_e       = 0x10,
+    fss_read_main_flag_copyright_e              = 0x20,
+    fss_read_main_flag_delimit_e                = 0x40,
+    fss_read_main_flag_depth_e                  = 0x80,
+    fss_read_main_flag_depth_multiple_e         = 0x100,
+    fss_read_main_flag_empty_e                  = 0x200,
+    fss_read_main_flag_help_e                   = 0x400,
+    fss_read_main_flag_line_e                   = 0x800,
+    fss_read_main_flag_line_single_e            = 0x1000,
+    fss_read_main_flag_name_e                   = 0x2000,
+    fss_read_main_flag_object_e                 = 0x4000,
+    fss_read_main_flag_object_as_line_e         = 0x8000,
+    fss_read_main_flag_object_trim_e            = 0x10000,
+    fss_read_main_flag_original_e               = 0x20000,
+    fss_read_main_flag_payload_create_e         = 0x40000,
+    fss_read_main_flag_payload_error_e          = 0x80000,
+    fss_read_main_flag_payload_warn_e           = 0x100000,
+    fss_read_main_flag_pipe_e                   = 0x200000,
+    fss_read_main_flag_pipe_format_e            = 0x400000,
+    fss_read_main_flag_print_first_e            = 0x800000,
+    fss_read_main_flag_print_last_e             = 0x1000000,
+    fss_read_main_flag_quote_content_e          = 0x2000000,
+    fss_read_main_flag_quote_object_e           = 0x4000000,
+    fss_read_main_flag_select_e                 = 0x8000000,
+    fss_read_main_flag_total_e                  = 0x10000000,
+    fss_read_main_flag_trim_e                   = 0x20000000,
+    fss_read_main_flag_trim_object_e            = 0x40000000,
+    fss_read_main_flag_version_e                = 0x80000000,
+    fss_read_main_flag_version_copyright_help_e = 0x80000420,
   }; // enum
 #endif // _di_fss_read_main_flag_e_
 
@@ -137,7 +139,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(fss_read_short_trim_s,     fss_read_long_trim_s,     0, f_console_flag_normal_e), \
     }
 
-  #define fss_read_parameter_total_d 29
+  #define fss_read_parameter_total_d (f_console_parameter_state_type_total_d + 16)
 #endif // _di_fss_read_parameter_e_
 
 /**
index 1c3068e..9a6ec49 100644 (file)
@@ -66,7 +66,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (fss_read_main_flag_help_e | fss_read_main_flag_version_e | fss_read_main_flag_copyright_e)) {
+    if (main->setting.flag & fss_read_main_flag_version_copyright_help_e) {
       if (main->setting.flag & fss_read_main_flag_help_e) {
         if (main->callback.process_help) {
           main->callback.process_help(void_main);
index 96c17e1..f3c2172 100644 (file)
@@ -57,9 +57,9 @@ extern "C" {
     fl_print_format("%[%QThe parameter '%]", print->to, print->context, print->prefix, print->context);
     fl_print_format(f_string_format_rr_single_s.string, print->to, print->notable, symbol, name, print->notable);
     fl_print_format("%[' may not have the value '%]", print->to, print->context, print->context);
-    fl_print_format("%[%ul%]", print->to, print->notable, value, print->notable);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->notable, value, print->notable);
     fl_print_format("%[' before the value '%]", print->to, print->context, print->context);
-    fl_print_format("%[%ul%]", print->to, print->notable, before, print->notable);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->notable, before, print->notable);
     fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->context, print->context, f_string_eol_s);
 
     f_file_stream_unlock(print->to);
@@ -77,7 +77,7 @@ extern "C" {
     f_file_stream_lock(print->to);
 
     fl_print_format("%[%QThe value '%]", print->to, print->context, print->prefix, print->context);
-    fl_print_format("%[%ul%]", print->to, print->notable, value, print->notable);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->notable, value, print->notable);
     fl_print_format("%[' may only be specified once for the parameter '%]", print->to, print->context, print->context);
     fl_print_format(f_string_format_rr_single_s.string, print->to, print->notable, symbol, name, print->notable);
     fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->context, print->context, f_string_eol_s);
index e817d02..c18ada8 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_fss_read_thread_signal_) && !defined(_di_thread_support_)
   void * fss_read_thread_signal(void * const main) {
 
index cb3fafb..a7b1324 100644 (file)
@@ -120,7 +120,9 @@ extern "C" {
 
     if (!print || !print->set) return F_status_set_error(F_output_not);
 
-    fl_print_format("%r %[Special Options:%] %r", print->to, f_string_eol_s, print->set->important, print->set->important, f_string_eol_s);
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    fll_program_print_help_special_options(print);
 
     fll_program_print_help_option_long(print, fss_read_long_payload_s, f_console_symbol_long_normal_s, "Specify custom actions to perform when payload Object is missing.");
 
index 874347d..6e6c4b8 100644 (file)
@@ -20,44 +20,46 @@ extern "C" {
  * Flags passed to the main function or program.
  *
  * fss_write_main_flag_*_e:
- *   - none:             No flags set.
- *   - content:          The Content being written is specified.
- *   - content_end:      The Content end characters are to be printed.
- *   - content_multiple: Designate that multiple Content is allowed for an Object for this standard rather than a single Content per Object.
- *   - content_next:     The Content next characters are to be printed.
- *   - copyright:        Print copyright.
- *   - file_to:          Using a specified destination file.
- *   - help:             Print help.
- *   - ignore:           Ignore a given range within a Content (specify flag before setting loading to designate ignores is supported by standard).
- *   - object:           The Object being written is specified.
- *   - object_open:      The Object open characters are to be printed.
- *   - partial:          Do not write end of Object/Content character.
- *   - pipe:             Use the input pipe.
- *   - print_first:      When set, print new line to message output on program begin after loading settings.
- *   - print_last:       When set, print new line to message output on program end.
- *   - trim:             Trim Object names.
- *   - version:          Print version.
+ *   - none:                   No flags set.
+ *   - content:                The Content being written is specified.
+ *   - content_end:            The Content end characters are to be printed.
+ *   - content_multiple:       Designate that multiple Content is allowed for an Object for this standard rather than a single Content per Object.
+ *   - content_next:           The Content next characters are to be printed.
+ *   - copyright:              Print copyright.
+ *   - file_to:                Using a specified destination file.
+ *   - help:                   Print help.
+ *   - ignore:                 Ignore a given range within a Content (specify flag before setting loading to designate ignores is supported by standard).
+ *   - object:                 The Object being written is specified.
+ *   - object_open:            The Object open characters are to be printed.
+ *   - partial:                Do not write end of Object/Content character.
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - trim:                   Trim Object names.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
  */
 #ifndef _di_fss_write_main_flag_e_
   enum {
-    fss_write_main_flag_none_e             = 0x0,
-    fss_write_main_flag_content_e          = 0x1,
-    fss_write_main_flag_content_end_e      = 0x2,
-    fss_write_main_flag_content_multiple_e = 0x4,
-    fss_write_main_flag_content_next_e     = 0x8,
-    fss_write_main_flag_copyright_e        = 0x10,
-    fss_write_main_flag_file_to_e          = 0x20,
-    fss_write_main_flag_help_e             = 0x40,
-    fss_write_main_flag_ignore_e           = 0x80,
-    fss_write_main_flag_object_e           = 0x100,
-    fss_write_main_flag_object_open_e      = 0x200,
-    fss_write_main_flag_partial_e          = 0x400,
-    fss_write_main_flag_pipe_e             = 0x800,
-    fss_write_main_flag_prepend_e          = 0x1000,
-    fss_write_main_flag_print_first_e      = 0x2000,
-    fss_write_main_flag_print_last_e       = 0x4000,
-    fss_write_main_flag_trim_e             = 0x8000,
-    fss_write_main_flag_version_e          = 0x10000,
+    fss_write_main_flag_none_e                   = 0x0,
+    fss_write_main_flag_content_e                = 0x1,
+    fss_write_main_flag_content_end_e            = 0x2,
+    fss_write_main_flag_content_multiple_e       = 0x4,
+    fss_write_main_flag_content_next_e           = 0x8,
+    fss_write_main_flag_copyright_e              = 0x10,
+    fss_write_main_flag_file_to_e                = 0x20,
+    fss_write_main_flag_help_e                   = 0x40,
+    fss_write_main_flag_ignore_e                 = 0x80,
+    fss_write_main_flag_object_e                 = 0x100,
+    fss_write_main_flag_object_open_e            = 0x200,
+    fss_write_main_flag_partial_e                = 0x400,
+    fss_write_main_flag_pipe_e                   = 0x800,
+    fss_write_main_flag_prepend_e                = 0x1000,
+    fss_write_main_flag_print_first_e            = 0x2000,
+    fss_write_main_flag_print_last_e             = 0x4000,
+    fss_write_main_flag_trim_e                   = 0x8000,
+    fss_write_main_flag_version_e                = 0x10000,
+    fss_write_main_flag_version_copyright_help_e = 0x10050,
   }; // enum
 #endif // _di_fss_write_main_flag_e_
 
@@ -102,7 +104,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(fss_write_short_trim_s,         fss_write_long_trim_s,         0, f_console_flag_normal_e), \
     }
 
-  #define fss_write_parameter_total_d 27
+  #define fss_write_parameter_total_d (f_console_parameter_state_type_total_d + 14)
 #endif // _di_fss_write_parameter_e_
 
 /**
index 24f322f..d39a5c1 100644 (file)
@@ -25,7 +25,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (fss_write_main_flag_help_e | fss_write_main_flag_version_e | fss_write_main_flag_copyright_e)) {
+    if (main->setting.flag & fss_write_main_flag_version_copyright_help_e) {
       if (main->setting.flag & fss_write_main_flag_help_e) {
         if (main->callback.process_help) {
           main->callback.process_help(void_main);
index 8701f2f..9238266 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_fss_write_thread_signal_) && !defined(_di_thread_support_)
   void * fss_write_thread_signal(void * const main) {
 
index 6a112e1..bfdd46c 100644 (file)
@@ -20,47 +20,49 @@ extern "C" {
  * Flags passed to the main function or program.
  *
  * iki_read_main_flag_*_e:
- *   - none:        No flags set.
- *   - at:          Selecting at a specific index.
- *   - content:     Print Contents.
- *   - copyright:   Print copyright.
- *   - help:        Print help.
- *   - literal:     Print as literal data (printing entire variable).
- *   - line:        Selecting at a specific line.
- *   - name:        Selecting using a specific Vocabulary name.
- *   - object:      Print Objects.
- *   - pipe:        Use the input pipe.
- *   - print_first: When set, print new line to message output on program begin after loading settings.
- *   - print_last:  When set, print new line to message output on program end.
- *   - replace:     Using re-assignments.
- *   - replace:     Using replacements.
- *   - substitute:  Using substitutions.
- *   - total:       Enable printing of "total" count.
- *   - version:     Print version.
- *   - whole:       Print all data.
- *   - wrap:        Using wrapping.
+ *   - none:                   No flags set.
+ *   - at:                     Selecting at a specific index.
+ *   - content:                Print Contents.
+ *   - copyright:              Print copyright.
+ *   - help:                   Print help.
+ *   - literal:                Print as literal data (printing entire variable).
+ *   - line:                   Selecting at a specific line.
+ *   - name:                   Selecting using a specific Vocabulary name.
+ *   - object:                 Print Objects.
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - replace:                Using re-assignments.
+ *   - replace:                Using replacements.
+ *   - substitute:             Using substitutions.
+ *   - total:                  Enable printing of "total" count.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
+ *   - whole:                  Print all data.
+ *   - wrap:                   Using wrapping.
  */
 #ifndef _di_iki_read_main_flag_e_
   enum {
-    iki_read_main_flag_none_e        = 0x0,
-    iki_read_main_flag_at_e          = 0x1,
-    iki_read_main_flag_content_e     = 0x2,
-    iki_read_main_flag_copyright_e   = 0x4,
-    iki_read_main_flag_help_e        = 0x8,
-    iki_read_main_flag_literal_e     = 0x10,
-    iki_read_main_flag_line_e        = 0x20,
-    iki_read_main_flag_name_e        = 0x40,
-    iki_read_main_flag_object_e      = 0x80,
-    iki_read_main_flag_pipe_e        = 0x100,
-    iki_read_main_flag_print_first_e = 0x200,
-    iki_read_main_flag_print_last_e  = 0x400,
-    iki_read_main_flag_reassign_e    = 0x800,
-    iki_read_main_flag_replace_e     = 0x1000,
-    iki_read_main_flag_substitute_e  = 0x2000,
-    iki_read_main_flag_total_e       = 0x4000,
-    iki_read_main_flag_version_e     = 0x8000,
-    iki_read_main_flag_whole_e       = 0x10000,
-    iki_read_main_flag_wrap_e        = 0x20000,
+    iki_read_main_flag_none_e                   = 0x0,
+    iki_read_main_flag_at_e                     = 0x1,
+    iki_read_main_flag_content_e                = 0x2,
+    iki_read_main_flag_copyright_e              = 0x4,
+    iki_read_main_flag_help_e                   = 0x8,
+    iki_read_main_flag_literal_e                = 0x10,
+    iki_read_main_flag_line_e                   = 0x20,
+    iki_read_main_flag_name_e                   = 0x40,
+    iki_read_main_flag_object_e                 = 0x80,
+    iki_read_main_flag_pipe_e                   = 0x100,
+    iki_read_main_flag_print_first_e            = 0x200,
+    iki_read_main_flag_print_last_e             = 0x400,
+    iki_read_main_flag_reassign_e               = 0x800,
+    iki_read_main_flag_replace_e                = 0x1000,
+    iki_read_main_flag_substitute_e             = 0x2000,
+    iki_read_main_flag_total_e                  = 0x4000,
+    iki_read_main_flag_version_e                = 0x8000,
+    iki_read_main_flag_version_copyright_help_e = 0x800c,
+    iki_read_main_flag_whole_e                  = 0x10000,
+    iki_read_main_flag_wrap_e                   = 0x20000,
   }; // enum
 #endif // _di_iki_read_main_flag_e_
 
@@ -101,7 +103,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(iki_read_short_wrap_s,       iki_read_long_wrap_s,       3, f_console_flag_normal_e), \
     }
 
-  #define iki_read_parameter_total_d 25
+  #define iki_read_parameter_total_d (f_console_parameter_state_type_total_d + 12)
 #endif // _di_iki_read_parameter_e_
 
 /**
index aae7cc7..790602f 100644 (file)
@@ -23,7 +23,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (iki_read_main_flag_help_e | iki_read_main_flag_version_e | iki_read_main_flag_copyright_e)) {
+    if (main->setting.flag & iki_read_main_flag_version_copyright_help_e) {
       if (main->setting.flag & iki_read_main_flag_help_e) {
         iki_read_print_message_help(&main->program.message);
       }
index b9fdac7..170dba1 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
  *   The output structure to print to.
  *
  *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
  *
  * @return
  *   F_okay on success.
index a71a418..449842c 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_iki_read_thread_signal_) && !defined(_di_thread_support_)
   void * iki_read_thread_signal(void * const main) {
 
index a141a8f..c7935a3 100644 (file)
@@ -20,32 +20,34 @@ extern "C" {
  * Flags passed to the main function or program.
  *
  * iki_write_main_flag_*_e:
- *   - none:        No flags set.
- *   - content:     The Content being written is specified.
- *   - copyright:   Print copyright.
- *   - file_to:     Using a specified destination file.
- *   - help:        Print help.
- *   - object:      The Object being written is specified.
- *   - pipe:        Use the input pipe.
- *   - print_first: When set, print new line to message output on program begin after loading settings.
- *   - print_last:  When set, print new line to message output on program end.
- *   - print_last:  The Object being written is specified.
- *   - version:     Print version.
- *   - wrap:        Wrap the vocabulary.
+ *   - none:                   No flags set.
+ *   - content:                The Content being written is specified.
+ *   - copyright:              Print copyright.
+ *   - file_to:                Using a specified destination file.
+ *   - help:                   Print help.
+ *   - object:                 The Object being written is specified.
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - print_last:             The Object being written is specified.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
+ *   - wrap:                   Wrap the vocabulary.
  */
 #ifndef _di_iki_write_main_flag_e_
   enum {
-    iki_write_main_flag_none_e        = 0x0,
-    iki_write_main_flag_content_e     = 0x1,
-    iki_write_main_flag_copyright_e   = 0x2,
-    iki_write_main_flag_file_to_e     = 0x4,
-    iki_write_main_flag_help_e        = 0x8,
-    iki_write_main_flag_object_e      = 0x10,
-    iki_write_main_flag_pipe_e        = 0x20,
-    iki_write_main_flag_print_first_e = 0x40,
-    iki_write_main_flag_print_last_e  = 0x80,
-    iki_write_main_flag_version_e     = 0x100,
-    iki_write_main_flag_wrap_e        = 0x200,
+    iki_write_main_flag_none_e                   = 0x0,
+    iki_write_main_flag_content_e                = 0x1,
+    iki_write_main_flag_copyright_e              = 0x2,
+    iki_write_main_flag_file_to_e                = 0x4,
+    iki_write_main_flag_help_e                   = 0x8,
+    iki_write_main_flag_object_e                 = 0x10,
+    iki_write_main_flag_pipe_e                   = 0x20,
+    iki_write_main_flag_print_first_e            = 0x40,
+    iki_write_main_flag_print_last_e             = 0x80,
+    iki_write_main_flag_version_e                = 0x100,
+    iki_write_main_flag_version_copyright_help_e = 0x10a,
+    iki_write_main_flag_wrap_e                   = 0x200,
   }; // enum
 #endif // _di_iki_write_main_flag_e_
 
@@ -76,7 +78,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(iki_write_short_wrap_s,    iki_write_long_wrap_s,    0, f_console_flag_normal_e), \
     }
 
-  #define iki_write_parameter_total_d 20
+  #define iki_write_parameter_total_d (f_console_parameter_state_type_total_d + 7)
 #endif // _di_iki_write_parameter_e_
 
 /**
index 9b370de..17deee2 100644 (file)
@@ -23,7 +23,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (iki_write_main_flag_help_e | iki_write_main_flag_version_e | iki_write_main_flag_copyright_e)) {
+    if (main->setting.flag & iki_write_main_flag_version_copyright_help_e) {
       if (main->setting.flag & iki_write_main_flag_help_e) {
         iki_write_print_message_help(&main->program.message);
       }
index 7727063..5febb6c 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
  *   The output structure to print to.
  *
  *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
  *
  * @return
  *   F_okay on success.
index f67796e..f4aff1b 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_iki_write_thread_signal_) && !defined(_di_thread_support_)
   void * iki_write_thread_signal(void * const main) {
 
index b751f2c..b3bf49c 100644 (file)
@@ -22,31 +22,33 @@ extern "C" {
  * When number mode is not specified, then mode is "string" mode (there is no flag for "string" mode).
  *
  * status_code_main_flag_*_e:
- *   - none:        No flags set.
- *   - copyright:   Print copyright.
- *   - error:       Check if status is "error".
- *   - fine:        Check if status is "fine".
- *   - help:        Print help.
- *   - number:      Operate in number mode.
- *   - pipe:        Use the input pipe.
- *   - print_first: When set, print new line to message output on program begin after loading settings.
- *   - print_last:  When set, print new line to message output on program end.
- *   - version:     Print version.
- *   - warning:     Check if status is "warning".
+ *   - none:                   No flags set.
+ *   - copyright:              Print copyright.
+ *   - error:                  Check if status is "error".
+ *   - fine:                   Check if status is "fine".
+ *   - help:                   Print help.
+ *   - number:                 Operate in number mode.
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
+ *   - warning:                Check if status is "warning".
  */
 #ifndef _di_status_code_main_flag_e_
   enum {
-    status_code_main_flag_none_e        = 0x0,
-    status_code_main_flag_copyright_e   = 0x1,
-    status_code_main_flag_error_e       = 0x2,
-    status_code_main_flag_fine_e        = 0x4,
-    status_code_main_flag_help_e        = 0x8,
-    status_code_main_flag_number_e      = 0x10,
-    status_code_main_flag_pipe_e        = 0x20,
-    status_code_main_flag_print_first_e = 0x40,
-    status_code_main_flag_print_last_e  = 0x80,
-    status_code_main_flag_version_e     = 0x100,
-    status_code_main_flag_warning_e     = 0x200,
+    status_code_main_flag_none_e                   = 0x0,
+    status_code_main_flag_copyright_e              = 0x1,
+    status_code_main_flag_error_e                  = 0x2,
+    status_code_main_flag_fine_e                   = 0x4,
+    status_code_main_flag_help_e                   = 0x8,
+    status_code_main_flag_number_e                 = 0x10,
+    status_code_main_flag_pipe_e                   = 0x20,
+    status_code_main_flag_print_first_e            = 0x40,
+    status_code_main_flag_print_last_e             = 0x80,
+    status_code_main_flag_version_e                = 0x100,
+    status_code_main_flag_version_copyright_help_e = 0x109,
+    status_code_main_flag_warning_e                = 0x200,
   }; // enum
 #endif // _di_status_code_main_flag_e_
 
@@ -71,7 +73,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(status_code_short_number_s,  status_code_long_number_s,  0, f_console_flag_normal_e), \
     }
 
-  #define status_code_parameter_total_d 17
+  #define status_code_parameter_total_d (f_console_parameter_state_type_total_d + 4)
 #endif // _di_status_code_parameter_e_
 
 /**
index b57b4d0..48531ec 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
  *   The output structure to print to.
  *
  *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
  *
  * @return
  *   F_okay on success.
index e3f5e6b..77a794a 100644 (file)
@@ -41,7 +41,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (status_code_main_flag_help_e | status_code_main_flag_version_e | status_code_main_flag_copyright_e)) {
+    if (main->setting.flag & status_code_main_flag_version_copyright_help_e) {
       if (main->setting.flag & status_code_main_flag_help_e) {
         status_code_print_message_help(&main->program.message);
       }
index bb8d999..e01e9ae 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_status_code_thread_signal_) && !defined(_di_thread_support_)
   void * status_code_thread_signal(void * const main) {
 
index 35f5819..3bf3822 100644 (file)
@@ -48,35 +48,37 @@ extern "C" {
  * Flags passed to the main function or program.
  *
  * utf8_main_flag_*_e:
- *   - none:          No flags set.
- *   - copyright:     Print the copyright.
- *   - file_from:     Using a specified source file.
- *   - file_to:       Using a specified destination file.
- *   - header:        Enable printing of headers.
- *   - help:          Print help.
- *   - pipe:          Use the input pipe.
- *   - print_first:   When set, print new line to message output on program begin after loading settings.
- *   - print_last:    When set, print new line to message output on program end.
- *   - separate:      Enable printing of separators.
- *   - strip_invalid: Using strip invalid character mode.
- *   - verify:        Using verify mode.
- *   - version:       Print version.
+ *   - none:                   No flags set.
+ *   - copyright:              Print the copyright.
+ *   - file_from:              Using a specified source file.
+ *   - file_to:                Using a specified destination file.
+ *   - header:                 Enable printing of headers.
+ *   - help:                   Print help.
+ *   - pipe:                   Use the input pipe.
+ *   - print_first:            When set, print new line to message output on program begin after loading settings.
+ *   - print_last:             When set, print new line to message output on program end.
+ *   - separate:               Enable printing of separators.
+ *   - strip_invalid:          Using strip invalid character mode.
+ *   - verify:                 Using verify mode.
+ *   - version:                Print version.
+ *   - version_copyright_help: A helper flag representing version, copyright, and help flag bits being set.
  */
 #ifndef _di_utf8_main_flag_e_
   enum {
-    utf8_main_flag_none_e          = 0x0,
-    utf8_main_flag_copyright_e     = 0x1,
-    utf8_main_flag_file_from_e     = 0x2,
-    utf8_main_flag_file_to_e       = 0x4,
-    utf8_main_flag_header_e        = 0x8,
-    utf8_main_flag_help_e          = 0x10,
-    utf8_main_flag_pipe_e          = 0x20,
-    utf8_main_flag_print_first_e   = 0x40,
-    utf8_main_flag_print_last_e    = 0x80,
-    utf8_main_flag_separate_e      = 0x100,
-    utf8_main_flag_strip_invalid_e = 0x200,
-    utf8_main_flag_verify_e        = 0x400,
-    utf8_main_flag_version_e       = 0x800,
+    utf8_main_flag_none_e                   = 0x0,
+    utf8_main_flag_copyright_e              = 0x1,
+    utf8_main_flag_file_from_e              = 0x2,
+    utf8_main_flag_file_to_e                = 0x4,
+    utf8_main_flag_header_e                 = 0x8,
+    utf8_main_flag_help_e                   = 0x10,
+    utf8_main_flag_pipe_e                   = 0x20,
+    utf8_main_flag_print_first_e            = 0x40,
+    utf8_main_flag_print_last_e             = 0x80,
+    utf8_main_flag_separate_e               = 0x100,
+    utf8_main_flag_strip_invalid_e          = 0x200,
+    utf8_main_flag_verify_e                 = 0x400,
+    utf8_main_flag_version_e                = 0x800,
+    utf8_main_flag_version_copyright_help_e = 0x811,
   }; // enum
 #endif // _di_utf8_main_flag_e_
 
@@ -153,7 +155,7 @@ extern "C" {
       macro_f_console_parameter_t_initialize_3(utf8_short_verify_s,            utf8_long_verify_s,            0, f_console_flag_normal_e), \
     }
 
-  #define utf8_parameter_total_d 25
+  #define utf8_parameter_total_d (f_console_parameter_state_type_total_d + 12)
 #endif // _di_utf8_parameter_e_
 
 /**
index 6c8e8c2..edbe962 100644 (file)
@@ -48,8 +48,8 @@ extern "C" {
       fl_print_format("%[', invalid UTF-8 fragment.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
     }
     else {
-      fl_print_format("%[', error status code%] ", print->to, print->set->error, print->set->error, f_string_eol_s);
-      fl_print_format("%[%ui%]", print->to, print->set->notable, F_status_set_fine(main->setting.state.status), print->set->notable);
+      fl_print_format("%[', error code%] ", print->to, print->set->error, print->set->error, f_string_eol_s);
+      fl_print_format(f_string_format_ui_single_s.string, print->to, print->set->notable, F_status_set_fine(main->setting.state.status), print->set->notable);
       fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
     }
 
@@ -74,8 +74,8 @@ extern "C" {
       fl_print_format("%[', not a valid Unicode codepoint.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
     }
     else {
-      fl_print_format("%[', error status code%] ", print->to, print->set->error, print->set->error, f_string_eol_s);
-      fl_print_format("%[%ui%]", print->to, print->set->notable, F_status_set_fine(main->setting.state.status), print->set->notable);
+      fl_print_format("%[', error code%] ", print->to, print->set->error, print->set->error, f_string_eol_s);
+      fl_print_format(f_string_format_ui_single_s.string, print->to, print->set->notable, F_status_set_fine(main->setting.state.status), print->set->notable);
       fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
     }
 
@@ -118,7 +118,7 @@ extern "C" {
     f_file_stream_lock(print->to);
 
     fl_print_format("%[%QNo file specified at parameter index%] ", print->to, print->set->error, print->prefix, print->set->error);
-    fl_print_format("%[%ul%]", print->to, print->set->notable, index, print->set->notable);
+    fl_print_format(f_string_format_ul_single_s.string, print->to, print->set->notable, index, print->set->notable);
     fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
 
     f_file_stream_unlock(print->to);
index b97319e..fedc9d6 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
  *   The output structure to print to.
  *
  *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function associated with the error.
  *
  * @return
  *   F_okay on success.
index c5449e4..ba7b349 100644 (file)
@@ -4,10 +4,6 @@
 extern "C" {
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if !defined(_di_utf8_thread_signal_) && !defined(_di_thread_support_)
   void * utf8_thread_signal(void * const main) {
 
index 60d0b82..67de3a3 100644 (file)
@@ -23,7 +23,7 @@ extern "C" {
 
     main->setting.state.status = F_okay;
 
-    if (main->setting.flag & (utf8_main_flag_help_e | utf8_main_flag_version_e | utf8_main_flag_copyright_e)) {
+    if (main->setting.flag & utf8_main_flag_version_copyright_help_e) {
       if (main->setting.flag & utf8_main_flag_help_e) {
         utf8_print_message_help(&main->program.message);
       }
@@ -166,15 +166,9 @@ extern "C" {
       }
     }
 
-    if (F_status_set_fine(main->setting.state.status) == F_interrupt) return;
-    if (F_status_is_error(main->setting.state.status)) return;
+    if (F_status_is_error(main->setting.state.status) || main->setting.state.status == F_interrupt) return;
 
-    if (main->setting.flag & utf8_main_flag_verify_e) {
-      main->setting.state.status = valid;
-    }
-    else {
-      main->setting.state.status = F_okay;
-    }
+    main->setting.state.status = (main->setting.flag & utf8_main_flag_verify_e) ? valid : F_okay;
   }
 #endif // _di_utf8_main_