]> 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 68b0703df35bdcce045e3b7c389782bdec75ef78..31e520eda4da44ca486a5ece984c199dafd1625d 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 8539e7467f96ea9d6b412e9ad57c3fe624d128d7..50f98fdb814c6ff7d4bfee6cc0f5243b3d426f36 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 9ddcc62653b428aa65910dd3c5f0fd1a7f16ad1c..b0d04634b0a572a4063f02df719f83ceba59d74b 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 b53a6b40b36050d4bb3b4f6e5c9fb7b889fb5c59..0b4663b05fcf4a916202d77212d0b271b2eb9c78 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 adf8c283905acebc5fa5446c7a5303942bc3a8c5..24c46fa1d8259c651eb2ab412d3403c14d505062 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 b5224cda9244d893c446a8835e0130c444cdefe3..7ac76c89f30bbaabfb2758f61cab0640a08139bb 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 c6e003eeadcae32ee04639f5b93de85b3dc2b98a..41cbdefe25f750c30a0daa5ab168fd722ca72e02 100644 (file)
@@ -814,6 +814,28 @@ extern "C" {
 #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.
  *
  * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
@@ -924,6 +946,28 @@ extern "C" {
 #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.
  *
  * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
index fc1af07565c646d29667007ea4104e10b5ccaae7..ce24620bb59fb0cc3ee2ba07d7c1c892c46f27c0 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 b1029808e01cd4b674f576aefe1bdee2c66308ae..87c33af3dd10c7ff1188d192814790c46e3a8aec 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 8134849fbf246d8b977e62880d26176c5f93a3b8..966ceb8120a4b970e3db698d756c165cc8e396f5 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 002cacdf5481a3c61435783269aab0d47a9e7eb4..07abea0f46792bc572aefbf2e4ca63fb59b4b87b 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 580aeeac32fde96064502d9df2b02511d326b5c0..f252cac6bef2e7712758840342c06a9a0823a58a 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 f68baf86be5339b7a2357ebec653b3d421e1d208..6d8d4c9f0b095c761cdd0ea18ed98e08598199f3 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 90d0999499abf914a743e695700ef9c1b918a007..5da619b1dc85e5a8ccc0c70a9b51a0be49434fb3 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 ec9be63d85224ddc8e6a5ea53cce4ae29c567c25..7914da078209d14df7b5585e4253a7ccb03c2473 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 291d488b35714fa5341bf4b65c98f2136bb79122..18c9ddb0be04abb534c59d24639bbc6fb02e54f7 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 f6d401f1eeeaeffec82681d67165f478b9821f77..8f084ff924f617a96e7eb8166e8111c26576e2e9 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 da05cc4942ec53eee266e30f3278085980c11209..fc34f4a76db35d65b0b7630a3119e05f62989cfd 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 b859f7af70bca497fe0dd255900bf4676a6a3cdb..c9a44e2cdcfb2af8d0e6145470b764e86cdb8aa3 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 f5a1d7ffa89447a2289256da880ee4f61a90732e..0b40131cb1f20b8a9576349a1efcd76ac0150bcb 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 23f00774116398f73c9b44c00ddaa92e9adce758..9797b1ba4aed7a9eb0c458cafb7f3d6adef8aaa0 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 d8013ade791b1b968f9397a141e636b8d9bb1e5b..606446251125060e4a5aa0cfe0d6432631e1f7c0 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 97dc645e5c772a81abd09e48dc91406a46b67f42..dc4869bbd0378125b2548b8c2440dac86908cf89 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 0db1729c9006fea3d4c1dc24e56212318491ef3f..aae7120a6a70ee296ded5a58fddb9b4b52772f62 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 d5791b8cdd37c22cef7ba36f4f273b2d7d8684fb..2b4040aa1f35cd2cffbc729273f7000371847879 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 05e9d16485bd766c7eeed8d64f2af2af32665988..b8ead8cff761bc0471d72d148d363ba3e0838310 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 60b1d31f73623e3433daecfa54ad4bbb5b1eb43e..11131a479f6ab55d60fa442b539c08ea83edd34b 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 a123ce52dc9a97b8ec1ec9e3e2ec08e84e0c939f..8e7b884f7ca1686452db6d0381cc2dbc04ae0645 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 a84cdf914c2b8b670137f5b3de51538f972ef1b7..1c18b927a857f0010284090e80a998c24ec49a65 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 110e0f79d710ce2417ebf0bd6111845654b88347..5cbbefef8d72a9abc1aea68820cbbb132c71c91f 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 6b19cf74972b939c5c20414733694dd5904b5995..a71c4034acb6a42ee6bfcb5645fbca2f9d35537a 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 eda13ed468f2788248eb308411ef157cb8ce0a45..e9c3df3ace6bf6095d15304825cbeca6eb0833e2 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 75b514ab23e6f9d1d5d1dd9f4873fa680a5333fe..d14c13b578e9852ced24f881f21ae232efa93f9e 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 33c6a561d48251fcab6ff27d499f95954d6d2aac..02816c170efe466a40feeebc70d358c864ff5039 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 4404ee036d905adf7df9d645cc3980334f23ee46..9721206a83febdcc9e16744695efadf708c08c73 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 dc49243f24e8ff8f72a7980da4c310ae2480a4ab..c15ad1d952daabb7e061dca545e01edac8b6abdb 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 9e191b364dd46b59e21a886daeb0492caa665961..1805e949bcf3e3d11f4c6cafd31eb1065d6011e8 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 fbbadc425e000aa88e27635ce8d2e5c95a2bf8e2..96d2366884c41778bfd84c421047ddfd0f024267 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 8bfaeebda10592443f0c0a853a73e71570bc4d25..537250d2fa80232101d4d98851e3ae814d63c50d 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 594b181720e00978ad542d09b84af6b1594d771e..3e2a64f8dc372fa91bc682856e60ead711daee80 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 fc998a797fd445e95dd508a35a38ea7e8044c4b6..8b64f5fc0ff3218628e308e84287aabd18d4a2d7 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 0dea44021a804dd6dd48c7d2adad93f343d2e746..eca32d6b277fadd4e539627990c82acda77449f4 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 6196bd2cab02ddfd7bc7e13e7c1f5f0938545c55..6f9c1c974a0307dae4756f57c7876b943cd513e2 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 5bd7227850214e63723d752bb024396373a953cf..04d95ba94eff5e5793a027e20f7b5e1bdff55c0a 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 1c3068e8f111f9050c801f3e746ae2cea1979441..9a6ec49be7182f55023377a31a917dd4b418ec0e 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 96c17e1de1c2ae0afc6c9313bafe168bb5f2c44e..f3c21725053bcae518510d4942cda595dfb2c1ca 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 e817d02f83d07cb7699c208948c2a73f1b6bbd9b..c18ada813a324981198e615ab5264e49484ddb0c 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 cb3fafbb7f8f5ecc6d0f3d19245892aa0da59cf0..a7b1324432e89fbc0a52cd2d5d14f73cb400f59a 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 874347dc748bb1c3069e32cea353fa7bf50544dc..6e6c4b86ad32c32e9e72a4bbc3b8c89e80af8640 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 24f322f7155eb3d05247ee546e7c4cb01fd6428b..d39a5c12b901f077c36bbba8ff58b73083cb48ea 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 8701f2fbeb34e8037ec771f2b73b6c724db6d344..923826654f3e2385272c72fbeac5d1fcd0c58ffe 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 6a112e17e59016b66d7d8521d90fde24ae678956..bfdd46c6700d4312ff57fd869a30498376870743 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 aae7cc7e1a39d1517b165c340a644f231bb2e381..790602fa9f05dc3b0d0cda263f0bbe1c4fb6ea89 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 b9fdac7baab34aef0d176c5d53efd0532c8207e8..170dba15410fec977c273642e53e1c04d6c4e597 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 a71a41899176ab171afa50a2b0c90e10751f6668..449842c46fd1da8d9a4942c5c036bc34ce7d4657 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 a141a8f5bc0764e5ab94d4c447ce740cae320b51..c7935a3fef3166bab862b642bbf02dd7f79e0081 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 9b370dec01bd980bdc6fcc7652b5ffb81268577b..17deee2e220138812785321cf64b849c53b0c603 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 7727063d2464d02fb2e64ddf22870d02b636baab..5febb6c2e8fa8bf92c51d9dfa0713feb344443c3 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 f67796e7b6d3577d6790171f89a7d394491908be..f4aff1bc1451fca628dd7a68f40d1345063520a6 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 b751f2c674c38af596408e2d24f69fece61a3413..b3bf49c742adb326f91ef3c0e1848d5fedbac16a 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 b57b4d0c4265071b8a4a1f536b1d4cfdef101924..48531ecd6702b9e2eafec4f975a416b2cac86cec 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 e3f5e6b6312192c46cc19d311853e23f2c97a2ec..77a794a077f25f95c252a927b97f05374d4c4809 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 bb8d99919a6d2f346290fd60e1f5717c0bfdb3e9..e01e9ae8fcc1c7ef461516fa9eb9f670d3747849 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 35f5819100c4b0068a2810b06f6cba21db729058..3bf3822cdda556e72881f6bff2ff546dd36664a8 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 6c8e8c2d29f59b74e6e9f74f7a466b8c2ef42b7b..edbe9628a59d22e2cf86e5a93c8312b9c6a51b3b 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 b97319e851d4840f0bce9d051f72405cc3d40dcd..fedc9d6245dbdc9e53b884044631f830716abc11 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 c5449e420694a1d68675466ac360073b26909f0b..ba7b34962a249cd02af255b50719650d3ceb526b 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 60d0b8200a8cec8cc5d4c65e5628d22d20d70d5c..67de3a35edcc1f9c3716fea84005218c9a9f1799 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_