From: Kevin Day Date: Sun, 11 Feb 2024 04:14:23 +0000 (-0600) Subject: Progress: Refactoring firewall from 0.6.x to 0.7.x/0.8.x and other FLL project wide... X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=0fc432e326255224e5393efb325713c928df9e3c;p=fll Progress: Refactoring firewall from 0.6.x to 0.7.x/0.8.x and other FLL project wide changes. 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. --- diff --git a/build/disable/level_2/fll_program.h b/build/disable/level_2/fll_program.h index 68b0703..31e520e 100644 --- a/build/disable/level_2/fll_program.h +++ b/build/disable/level_2/fll_program.h @@ -42,10 +42,12 @@ #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_ diff --git a/build/stand_alone/fake.config.h b/build/stand_alone/fake.config.h index 8539e74..50f98fd 100644 --- a/build/stand_alone/fake.config.h +++ b/build/stand_alone/fake.config.h @@ -981,10 +981,12 @@ #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_ diff --git a/level_0/f_console/c/console/common.h b/level_0/f_console/c/console/common.h index 9ddcc62..b0d0463 100644 --- a/level_0/f_console/c/console/common.h +++ b/level_0/f_console/c/console/common.h @@ -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_ /** diff --git a/level_0/f_string/c/string/static.c b/level_0/f_string/c/string/static.c index b53a6b4..0b4663b 100644 --- a/level_0/f_string/c/string/static.c +++ b/level_0/f_string/c/string/static.c @@ -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 diff --git a/level_0/f_string/c/string/static.h b/level_0/f_string/c/string/static.h index adf8c28..24c46fa 100644 --- a/level_0/f_string/c/string/static.h +++ b/level_0/f_string/c/string/static.h @@ -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_ /** diff --git a/level_2/fll_program/c/program/print.c b/level_2/fll_program/c/program/print.c index b5224cd..7ac76c8 100644 --- a/level_2/fll_program/c/program/print.c +++ b/level_2/fll_program/c/program/print.c @@ -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); diff --git a/level_2/fll_program/c/program/print.h b/level_2/fll_program/c/program/print.h index c6e003e..41cbdef 100644 --- a/level_2/fll_program/c/program/print.h +++ b/level_2/fll_program/c/program/print.h @@ -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. diff --git a/level_3/byte_dump/c/main/byte_dump.c b/level_3/byte_dump/c/main/byte_dump.c index fc1af07..ce24620 100644 --- a/level_3/byte_dump/c/main/byte_dump.c +++ b/level_3/byte_dump/c/main/byte_dump.c @@ -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); } diff --git a/level_3/byte_dump/c/main/common/enumeration.h b/level_3/byte_dump/c/main/common/enumeration.h index b102980..87c33af 100644 --- a/level_3/byte_dump/c/main/common/enumeration.h +++ b/level_3/byte_dump/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/byte_dump/c/main/print/error.c b/level_3/byte_dump/c/main/print/error.c index 8134849..966ceb8 100644 --- a/level_3/byte_dump/c/main/print/error.c +++ b/level_3/byte_dump/c/main/print/error.c @@ -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); diff --git a/level_3/byte_dump/c/main/print/error.h b/level_3/byte_dump/c/main/print/error.h index 002cacd..07abea0 100644 --- a/level_3/byte_dump/c/main/print/error.h +++ b/level_3/byte_dump/c/main/print/error.h @@ -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. diff --git a/level_3/byte_dump/c/main/print/message.c b/level_3/byte_dump/c/main/print/message.c index 580aeea..f252cac 100644 --- a/level_3/byte_dump/c/main/print/message.c +++ b/level_3/byte_dump/c/main/print/message.c @@ -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."); diff --git a/level_3/byte_dump/c/main/thread.c b/level_3/byte_dump/c/main/thread.c index f68baf8..6d8d4c9 100644 --- a/level_3/byte_dump/c/main/thread.c +++ b/level_3/byte_dump/c/main/thread.c @@ -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) { diff --git a/level_3/control/c/main/common/enumeration.h b/level_3/control/c/main/common/enumeration.h index 90d0999..5da619b 100644 --- a/level_3/control/c/main/common/enumeration.h +++ b/level_3/control/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/control/c/main/control.c b/level_3/control/c/main/control.c index ec9be63..7914da0 100644 --- a/level_3/control/c/main/control.c +++ b/level_3/control/c/main/control.c @@ -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); } diff --git a/level_3/control/c/main/print/error.c b/level_3/control/c/main/print/error.c index 291d488..18c9ddb 100644 --- a/level_3/control/c/main/print/error.c +++ b/level_3/control/c/main/print/error.c @@ -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); diff --git a/level_3/control/c/main/print/error.h b/level_3/control/c/main/print/error.h index f6d401f..8f084ff 100644 --- a/level_3/control/c/main/print/error.h +++ b/level_3/control/c/main/print/error.h @@ -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. diff --git a/level_3/control/c/main/print/warning.c b/level_3/control/c/main/print/warning.c index da05cc4..fc34f4a 100644 --- a/level_3/control/c/main/print/warning.c +++ b/level_3/control/c/main/print/warning.c @@ -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); diff --git a/level_3/control/c/main/thread.c b/level_3/control/c/main/thread.c index b859f7a..c9a44e2 100644 --- a/level_3/control/c/main/thread.c +++ b/level_3/control/c/main/thread.c @@ -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) { diff --git a/level_3/controller/c/common.h b/level_3/controller/c/common.h index f5a1d7f..0b40131 100644 --- a/level_3/controller/c/common.h +++ b/level_3/controller/c/common.h @@ -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_ /** diff --git a/level_3/controller/c/controller/private-controller.c b/level_3/controller/c/controller/private-controller.c index 23f0077..9797b1b 100644 --- a/level_3/controller/c/controller/private-controller.c +++ b/level_3/controller/c/controller/private-controller.c @@ -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); diff --git a/level_3/controller/c/rule/private-rule.c b/level_3/controller/c/rule/private-rule.c index d8013ad..6064462 100644 --- a/level_3/controller/c/rule/private-rule.c +++ b/level_3/controller/c/rule/private-rule.c @@ -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 { diff --git a/level_3/fake/c/main/common/enumeration.h b/level_3/fake/c/main/common/enumeration.h index 97dc645..dc4869b 100644 --- a/level_3/fake/c/main/common/enumeration.h +++ b/level_3/fake/c/main/common/enumeration.h @@ -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_ diff --git a/level_3/fake/c/main/fake.c b/level_3/fake/c/main/fake.c index 0db1729..aae7120 100644 --- a/level_3/fake/c/main/fake.c +++ b/level_3/fake/c/main/fake.c @@ -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); } diff --git a/level_3/fake/c/main/print/error.c b/level_3/fake/c/main/print/error.c index d5791b8..2b4040a 100644 --- a/level_3/fake/c/main/print/error.c +++ b/level_3/fake/c/main/print/error.c @@ -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); diff --git a/level_3/fake/c/main/print/error.h b/level_3/fake/c/main/print/error.h index 05e9d16..b8ead8c 100644 --- a/level_3/fake/c/main/print/error.h +++ b/level_3/fake/c/main/print/error.h @@ -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. */ diff --git a/level_3/fake/c/main/print/message.c b/level_3/fake/c/main/print/message.c index 60b1d31..11131a4 100644 --- a/level_3/fake/c/main/print/message.c +++ b/level_3/fake/c/main/print/message.c @@ -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."); diff --git a/level_3/fake/c/main/print/verbose.h b/level_3/fake/c/main/print/verbose.h index a123ce5..8e7b884 100644 --- a/level_3/fake/c/main/print/verbose.h +++ b/level_3/fake/c/main/print/verbose.h @@ -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. */ diff --git a/level_3/fake/c/main/print/warning.h b/level_3/fake/c/main/print/warning.h index a84cdf9..1c18b92 100644 --- a/level_3/fake/c/main/print/warning.h +++ b/level_3/fake/c/main/print/warning.h @@ -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. */ diff --git a/level_3/fake/c/main/thread.c b/level_3/fake/c/main/thread.c index 110e0f7..5cbbefe 100644 --- a/level_3/fake/c/main/thread.c +++ b/level_3/fake/c/main/thread.c @@ -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 index a034d7c..0000000 --- a/level_3/firewall/c/firewall.c +++ /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 index 4522a86..0000000 --- a/level_3/firewall/c/firewall.h +++ /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 -#include -#include -#include - -// FLL-0 includes. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// FLL-1 includes. -#include - -// FLL-2 includes. -#include -#include -#include -#include -#include -#include -#include - -// Firewall includes. -#include -#include - -#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 index 0000000..4d28f17 --- /dev/null +++ b/level_3/firewall/c/main/common.c @@ -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 index 0000000..f262d22 --- /dev/null +++ b/level_3/firewall/c/main/common.h @@ -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 index 0000000..9bcd373 --- /dev/null +++ b/level_3/firewall/c/main/common/define.c @@ -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 index 0000000..9045d04 --- /dev/null +++ b/level_3/firewall/c/main/common/define.h @@ -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 index 0000000..9bcd373 --- /dev/null +++ b/level_3/firewall/c/main/common/enumeration.c @@ -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 index 0000000..d04d62f --- /dev/null +++ b/level_3/firewall/c/main/common/enumeration.h @@ -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 index 0000000..0567f9f --- /dev/null +++ b/level_3/firewall/c/main/common/print.c @@ -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 index 0000000..85b7a87 --- /dev/null +++ b/level_3/firewall/c/main/common/print.h @@ -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 diff --git a/level_3/firewall/c/common.c b/level_3/firewall/c/main/common/string.c similarity index 57% rename from level_3/firewall/c/common.c rename to level_3/firewall/c/main/common/string.c index 6b19cf7..a71c403 100644 --- a/level_3/firewall/c/common.c +++ b/level_3/firewall/c/main/common/string.c @@ -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" diff --git a/level_3/firewall/c/common.h b/level_3/firewall/c/main/common/string.h similarity index 50% rename from level_3/firewall/c/common.h rename to level_3/firewall/c/main/common/string.h index eda13ed..e9c3df3 100644 --- a/level_3/firewall/c/common.h +++ b/level_3/firewall/c/main/common/string.h @@ -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 index 0000000..21bea93 --- /dev/null +++ b/level_3/firewall/c/main/common/type.c @@ -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 index 0000000..ff541db --- /dev/null +++ b/level_3/firewall/c/main/common/type.h @@ -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 index 0000000..14fe05b --- /dev/null +++ b/level_3/firewall/c/main/firewall.c @@ -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 index 0000000..445b8c9 --- /dev/null +++ b/level_3/firewall/c/main/firewall.h @@ -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 + +// FLL-0 includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// FLL-1 includes. +#include +#include +#include + +// FLL-2 includes. +#include +#include +#include +#include + +// Firewall includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 diff --git a/level_3/firewall/c/main.c b/level_3/firewall/c/main/main.c similarity index 51% rename from level_3/firewall/c/main.c rename to level_3/firewall/c/main/main.c index 75b514a..d14c13b 100644 --- a/level_3/firewall/c/main.c +++ b/level_3/firewall/c/main/main.c @@ -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; } diff --git a/level_3/firewall/c/main.h b/level_3/firewall/c/main/main.h similarity index 97% rename from level_3/firewall/c/main.h rename to level_3/firewall/c/main/main.h index 33c6a56..02816c1 100644 --- a/level_3/firewall/c/main.h +++ b/level_3/firewall/c/main/main.h @@ -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 index 0000000..e1303fd --- /dev/null +++ b/level_3/firewall/c/main/operate.c @@ -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 index 0000000..ea54ede --- /dev/null +++ b/level_3/firewall/c/main/operate.h @@ -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 index 0000000..2544b42 --- /dev/null +++ b/level_3/firewall/c/main/operate/buffer.c @@ -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 index 0000000..ec4e9af --- /dev/null +++ b/level_3/firewall/c/main/operate/buffer.h @@ -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 index 0000000..0624b22 --- /dev/null +++ b/level_3/firewall/c/main/operate/create.c @@ -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 index 0000000..d3b8455 --- /dev/null +++ b/level_3/firewall/c/main/operate/create.h @@ -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 index 0000000..5b84d10 --- /dev/null +++ b/level_3/firewall/c/main/operate/default.c @@ -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 index 0000000..5fb890e --- /dev/null +++ b/level_3/firewall/c/main/operate/default.h @@ -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 index 0000000..95b72df --- /dev/null +++ b/level_3/firewall/c/main/operate/delete.c @@ -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 index 0000000..2b0a8a1 --- /dev/null +++ b/level_3/firewall/c/main/operate/delete.h @@ -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 index 0000000..9e558de --- /dev/null +++ b/level_3/firewall/c/main/operate/load.c @@ -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 index 0000000..e4b3632 --- /dev/null +++ b/level_3/firewall/c/main/operate/load.h @@ -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 index 0000000..d804c6a --- /dev/null +++ b/level_3/firewall/c/main/operate/process.c @@ -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 index 0000000..d3a612a --- /dev/null +++ b/level_3/firewall/c/main/operate/process.h @@ -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 index 0000000..9bcd373 --- /dev/null +++ b/level_3/firewall/c/main/print/data.c @@ -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 index 0000000..7b1da58 --- /dev/null +++ b/level_3/firewall/c/main/print/data.h @@ -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 index 0000000..d310f21 --- /dev/null +++ b/level_3/firewall/c/main/print/debug.c @@ -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 index 0000000..84a8f0a --- /dev/null +++ b/level_3/firewall/c/main/print/debug.h @@ -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 index 0000000..2ce2b5e --- /dev/null +++ b/level_3/firewall/c/main/print/error.c @@ -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 index 0000000..58334fa --- /dev/null +++ b/level_3/firewall/c/main/print/error.h @@ -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 index 0000000..71507b9 --- /dev/null +++ b/level_3/firewall/c/main/print/message.c @@ -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 index 0000000..b4d8c9e --- /dev/null +++ b/level_3/firewall/c/main/print/message.h @@ -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 index 0000000..9bcd373 --- /dev/null +++ b/level_3/firewall/c/main/print/verbose.c @@ -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 index 0000000..f00cf0c --- /dev/null +++ b/level_3/firewall/c/main/print/verbose.h @@ -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 index 0000000..428cbce --- /dev/null +++ b/level_3/firewall/c/main/print/warning.c @@ -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 index 0000000..0d1c509 --- /dev/null +++ b/level_3/firewall/c/main/print/warning.h @@ -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 index 0000000..76c63fc --- /dev/null +++ b/level_3/firewall/c/main/signal.c @@ -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 index 0000000..49156e3 --- /dev/null +++ b/level_3/firewall/c/main/signal.h @@ -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 index 0000000..b8803f5 --- /dev/null +++ b/level_3/firewall/c/main/thread.c @@ -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 index 0000000..12f6483 --- /dev/null +++ b/level_3/firewall/c/main/thread.h @@ -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 index 1a625d4..0000000 --- a/level_3/firewall/c/print.c +++ /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 index 6db7e94..0000000 --- a/level_3/firewall/c/print.h +++ /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 index 0c08398..0000000 --- a/level_3/firewall/c/private-common.c +++ /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 index 67e65a3..0000000 --- a/level_3/firewall/c/private-common.h +++ /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 index f8826af..0000000 --- a/level_3/firewall/c/private-firewall.c +++ /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 index 76ce290..0000000 --- a/level_3/firewall/c/private-firewall.h +++ /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 diff --git a/level_3/fss_identify/c/main/common/enumeration.h b/level_3/fss_identify/c/main/common/enumeration.h index 4404ee0..9721206 100644 --- a/level_3/fss_identify/c/main/common/enumeration.h +++ b/level_3/fss_identify/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/fss_identify/c/main/fss_identify.c b/level_3/fss_identify/c/main/fss_identify.c index dc49243..c15ad1d 100644 --- a/level_3/fss_identify/c/main/fss_identify.c +++ b/level_3/fss_identify/c/main/fss_identify.c @@ -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; } diff --git a/level_3/fss_identify/c/main/load.c b/level_3/fss_identify/c/main/load.c index 9e191b3..1805e94 100644 --- a/level_3/fss_identify/c/main/load.c +++ b/level_3/fss_identify/c/main/load.c @@ -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) { diff --git a/level_3/fss_identify/c/main/print/data.h b/level_3/fss_identify/c/main/print/data.h index fbbadc4..96d2366 100644 --- a/level_3/fss_identify/c/main/print/data.h +++ b/level_3/fss_identify/c/main/print/data.h @@ -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 diff --git a/level_3/fss_identify/c/main/print/error.c b/level_3/fss_identify/c/main/print/error.c index 8bfaeeb..537250d 100644 --- a/level_3/fss_identify/c/main/print/error.c +++ b/level_3/fss_identify/c/main/print/error.c @@ -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); diff --git a/level_3/fss_identify/c/main/print/error.h b/level_3/fss_identify/c/main/print/error.h index 594b181..3e2a64f 100644 --- a/level_3/fss_identify/c/main/print/error.h +++ b/level_3/fss_identify/c/main/print/error.h @@ -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. diff --git a/level_3/fss_identify/c/main/print/message.h b/level_3/fss_identify/c/main/print/message.h index fc998a7..8b64f5f 100644 --- a/level_3/fss_identify/c/main/print/message.h +++ b/level_3/fss_identify/c/main/print/message.h @@ -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. */ diff --git a/level_3/fss_identify/c/main/process.c b/level_3/fss_identify/c/main/process.c index 0dea440..eca32d6 100644 --- a/level_3/fss_identify/c/main/process.c +++ b/level_3/fss_identify/c/main/process.c @@ -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) { diff --git a/level_3/fss_identify/c/main/thread.c b/level_3/fss_identify/c/main/thread.c index 6196bd2..6f9c1c9 100644 --- a/level_3/fss_identify/c/main/thread.c +++ b/level_3/fss_identify/c/main/thread.c @@ -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) { diff --git a/level_3/fss_read/c/main/common/enumeration.h b/level_3/fss_read/c/main/common/enumeration.h index 5bd7227..04d95ba 100644 --- a/level_3/fss_read/c/main/common/enumeration.h +++ b/level_3/fss_read/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/fss_read/c/main/fss_read.c b/level_3/fss_read/c/main/fss_read.c index 1c3068e..9a6ec49 100644 --- a/level_3/fss_read/c/main/fss_read.c +++ b/level_3/fss_read/c/main/fss_read.c @@ -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); diff --git a/level_3/fss_read/c/main/print/error.c b/level_3/fss_read/c/main/print/error.c index 96c17e1..f3c2172 100644 --- a/level_3/fss_read/c/main/print/error.c +++ b/level_3/fss_read/c/main/print/error.c @@ -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); diff --git a/level_3/fss_read/c/main/thread.c b/level_3/fss_read/c/main/thread.c index e817d02..c18ada8 100644 --- a/level_3/fss_read/c/main/thread.c +++ b/level_3/fss_read/c/main/thread.c @@ -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) { diff --git a/level_3/fss_read/c/payload/print.c b/level_3/fss_read/c/payload/print.c index cb3fafb..a7b1324 100644 --- a/level_3/fss_read/c/payload/print.c +++ b/level_3/fss_read/c/payload/print.c @@ -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."); diff --git a/level_3/fss_write/c/main/common/enumeration.h b/level_3/fss_write/c/main/common/enumeration.h index 874347d..6e6c4b8 100644 --- a/level_3/fss_write/c/main/common/enumeration.h +++ b/level_3/fss_write/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/fss_write/c/main/fss_write.c b/level_3/fss_write/c/main/fss_write.c index 24f322f..d39a5c1 100644 --- a/level_3/fss_write/c/main/fss_write.c +++ b/level_3/fss_write/c/main/fss_write.c @@ -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); diff --git a/level_3/fss_write/c/main/thread.c b/level_3/fss_write/c/main/thread.c index 8701f2f..9238266 100644 --- a/level_3/fss_write/c/main/thread.c +++ b/level_3/fss_write/c/main/thread.c @@ -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) { diff --git a/level_3/iki_read/c/main/common/enumeration.h b/level_3/iki_read/c/main/common/enumeration.h index 6a112e1..bfdd46c 100644 --- a/level_3/iki_read/c/main/common/enumeration.h +++ b/level_3/iki_read/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/iki_read/c/main/iki_read.c b/level_3/iki_read/c/main/iki_read.c index aae7cc7..790602f 100644 --- a/level_3/iki_read/c/main/iki_read.c +++ b/level_3/iki_read/c/main/iki_read.c @@ -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); } diff --git a/level_3/iki_read/c/main/print/error.h b/level_3/iki_read/c/main/print/error.h index b9fdac7..170dba1 100644 --- a/level_3/iki_read/c/main/print/error.h +++ b/level_3/iki_read/c/main/print/error.h @@ -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. diff --git a/level_3/iki_read/c/main/thread.c b/level_3/iki_read/c/main/thread.c index a71a418..449842c 100644 --- a/level_3/iki_read/c/main/thread.c +++ b/level_3/iki_read/c/main/thread.c @@ -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) { diff --git a/level_3/iki_write/c/main/common/enumeration.h b/level_3/iki_write/c/main/common/enumeration.h index a141a8f..c7935a3 100644 --- a/level_3/iki_write/c/main/common/enumeration.h +++ b/level_3/iki_write/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/iki_write/c/main/iki_write.c b/level_3/iki_write/c/main/iki_write.c index 9b370de..17deee2 100644 --- a/level_3/iki_write/c/main/iki_write.c +++ b/level_3/iki_write/c/main/iki_write.c @@ -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); } diff --git a/level_3/iki_write/c/main/print/error.h b/level_3/iki_write/c/main/print/error.h index 7727063..5febb6c 100644 --- a/level_3/iki_write/c/main/print/error.h +++ b/level_3/iki_write/c/main/print/error.h @@ -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. diff --git a/level_3/iki_write/c/main/thread.c b/level_3/iki_write/c/main/thread.c index f67796e..f4aff1b 100644 --- a/level_3/iki_write/c/main/thread.c +++ b/level_3/iki_write/c/main/thread.c @@ -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) { diff --git a/level_3/status_code/c/main/common/enumeration.h b/level_3/status_code/c/main/common/enumeration.h index b751f2c..b3bf49c7 100644 --- a/level_3/status_code/c/main/common/enumeration.h +++ b/level_3/status_code/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/status_code/c/main/print/error.h b/level_3/status_code/c/main/print/error.h index b57b4d0..48531ec 100644 --- a/level_3/status_code/c/main/print/error.h +++ b/level_3/status_code/c/main/print/error.h @@ -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. diff --git a/level_3/status_code/c/main/status_code.c b/level_3/status_code/c/main/status_code.c index e3f5e6b..77a794a 100644 --- a/level_3/status_code/c/main/status_code.c +++ b/level_3/status_code/c/main/status_code.c @@ -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); } diff --git a/level_3/status_code/c/main/thread.c b/level_3/status_code/c/main/thread.c index bb8d999..e01e9ae 100644 --- a/level_3/status_code/c/main/thread.c +++ b/level_3/status_code/c/main/thread.c @@ -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) { diff --git a/level_3/utf8/c/main/common/enumeration.h b/level_3/utf8/c/main/common/enumeration.h index 35f5819..3bf3822 100644 --- a/level_3/utf8/c/main/common/enumeration.h +++ b/level_3/utf8/c/main/common/enumeration.h @@ -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_ /** diff --git a/level_3/utf8/c/main/print/error.c b/level_3/utf8/c/main/print/error.c index 6c8e8c2..edbe962 100644 --- a/level_3/utf8/c/main/print/error.c +++ b/level_3/utf8/c/main/print/error.c @@ -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); diff --git a/level_3/utf8/c/main/print/error.h b/level_3/utf8/c/main/print/error.h index b97319e..fedc9d6 100644 --- a/level_3/utf8/c/main/print/error.h +++ b/level_3/utf8/c/main/print/error.h @@ -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. diff --git a/level_3/utf8/c/main/thread.c b/level_3/utf8/c/main/thread.c index c5449e4..ba7b349 100644 --- a/level_3/utf8/c/main/thread.c +++ b/level_3/utf8/c/main/thread.c @@ -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) { diff --git a/level_3/utf8/c/main/utf8.c b/level_3/utf8/c/main/utf8.c index 60d0b82..67de3a3 100644 --- a/level_3/utf8/c/main/utf8.c +++ b/level_3/utf8/c/main/utf8.c @@ -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_