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.
#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_
#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_
* 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 {
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_
/**
#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
* 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_
/**
}
#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_
}
#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_
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);
#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.
#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.
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);
}
* 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_
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_
/**
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);
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);
* 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.
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.");
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) {
* 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_
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_
/**
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);
}
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);
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);
* 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_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);
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) {
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_
/**
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);
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);
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);
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);
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 {
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_
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);
}
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);
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);
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);
* 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.
*/
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.");
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.");
* 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.
*/
* 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.
*/
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) {
+++ /dev/null
-/**
- * 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
+++ /dev/null
-/**
- * FLL - Level 3
- *
- * Project: Firewall
- * API Version: 0.7
- * Licenses: lgpl-2.1-or-later
- *
- * This is the Kevux Operating System Firewall program.
- * This program utilizes the Featureless Linux Library.
- * This program processes firewall commands and passes them to iptables from netfiler.org.
- */
-#ifndef _firewall_h
-#define _firewall_h
-
-// Libc includes.
-#include <dirent.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-// FLL-0 includes.
-#include <fll/level_0/type.h>
-#include <fll/level_0/status.h>
-#include <fll/level_0/memory.h>
-#include <fll/level_0/type_array.h>
-#include <fll/level_0/string.h>
-#include <fll/level_0/utf.h>
-#include <fll/level_0/color.h>
-#include <fll/level_0/compare.h>
-#include <fll/level_0/console.h>
-#include <fll/level_0/directory.h>
-#include <fll/level_0/execute.h>
-#include <fll/level_0/file.h>
-#include <fll/level_0/pipe.h>
-#include <fll/level_0/print.h>
-#include <fll/level_0/rip.h>
-#include <fll/level_0/signal.h>
-
-// FLL-1 includes.
-#include <fll/level_1/print.h>
-
-// FLL-2 includes.
-#include <fll/level_2/error.h>
-#include <fll/level_2/execute.h>
-#include <fll/level_2/fss/basic.h>
-#include <fll/level_2/fss/basic_list.h>
-#include <fll/level_2/fss/extended.h>
-#include <fll/level_2/print.h>
-#include <fll/level_2/program.h>
-
-// Firewall includes.
-#include <program/firewall/common.h>
-#include <program/firewall/print.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Execute main program.
- *
- * If main.signal is non-zero, then this blocks and handles the following signals:
- * - F_signal_abort
- * - F_signal_broken_pipe
- * - F_signal_hangup
- * - F_signal_interrupt
- * - F_signal_quit
- * - F_signal_termination
- *
- * @param main
- * The main program data.
- * @param arguments
- * The parameters passed to the process.
- *
- * @return
- * F_okay on success.
- *
- * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal.
- *
- * Status codes (with error bit) are returned on any problem.
- */
-#ifndef _di_firewall_main_
- extern f_status_t firewall_main(fll_program_data_t * const main, firewall_setting_t * const setting);
-#endif // _di_firewall_main_
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // _firewall_h
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * 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
--- /dev/null
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
-#include "firewall.h"
+#include "../firewall.h"
#ifdef __cplusplus
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);
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);
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);
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"
* 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" {
* 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"
#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"
#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"
#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
#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
#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
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;
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;
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;
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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Firewall
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * This is the program is intended to be used to manage iptables.
+ *
+ * This program utilizes the Featureless Linux Library.
+ */
+#ifndef _firewall_h
+#define _firewall_h
+
+// Libc includes.
+#include <unistd.h>
+
+// FLL-0 includes.
+#include <fll/level_0/type.h>
+#include <fll/level_0/status.h>
+#include <fll/level_0/memory.h>
+#include <fll/level_0/string.h>
+#include <fll/level_0/utf.h>
+#include <fll/level_0/color.h>
+#include <fll/level_0/compare.h>
+#include <fll/level_0/console.h>
+#include <fll/level_0/conversion.h>
+#include <fll/level_0/directory.h>
+#include <fll/level_0/fss.h>
+#include <fll/level_0/file.h>
+#include <fll/level_0/pipe.h>
+#include <fll/level_0/print.h>
+#include <fll/level_0/rip.h>
+#include <fll/level_0/signal.h>
+#include <fll/level_0/thread.h>
+
+// FLL-1 includes.
+#include <fll/level_1/conversion.h>
+#include <fll/level_1/fss.h>
+#include <fll/level_1/print.h>
+
+// FLL-2 includes.
+#include <fll/level_2/error.h>
+#include <fll/level_2/fss.h>
+#include <fll/level_2/print.h>
+#include <fll/level_2/program.h>
+
+// Firewall includes.
+#include <program/firewall/main/common/define.h>
+#include <program/firewall/main/common/enumeration.h>
+#include <program/firewall/main/common/print.h>
+#include <program/firewall/main/common/string.h>
+#include <program/firewall/main/common/type.h>
+#include <program/firewall/main/common.h>
+#include <program/firewall/main/print/data.h>
+#include <program/firewall/main/print/debug.h>
+#include <program/firewall/main/print/error.h>
+#include <program/firewall/main/print/message.h>
+#include <program/firewall/main/print/verbose.h>
+#include <program/firewall/main/print/warning.h>
+#include <program/firewall/main/operate/buffer.h>
+#include <program/firewall/main/operate/create.h>
+#include <program/firewall/main/operate/default.h>
+#include <program/firewall/main/operate/delete.h>
+#include <program/firewall/main/operate/load.h>
+#include <program/firewall/main/operate/process.h>
+#include <program/firewall/main/signal.h>
+#include <program/firewall/main/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Execute main program.
+ *
+ * @param main
+ * The main program and setting data.
+ *
+ * This alters main.setting.state.status:
+ * F_okay on success.
+ *
+ * F_interrupt (with error bit) on interrupt signal received.
+ *
+ * Errors (with error bit) from: f_file_stream_open()
+ * Errors (with error bit) from: firewall_load_line()
+ * Errors (with error bit) from: firewall_process()
+ *
+ * @see f_file_stream_open()
+ * @see firewall_load_line()
+ * @see firewall_process()
+ */
+#ifndef _di_firewall_main_
+ extern void firewall_main(firewall_main_t * const main);
+#endif // _di_firewall_main_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_h
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;
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;
}
/**
* FLL - Level 3
*
- * Project: FSS Write
+ * Project: Firewall
* API Version: 0.7
* Licenses: lgpl-2.1-or-later
*
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#include "../firewall.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
+++ /dev/null
-#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
+++ /dev/null
-/**
- * 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
+++ /dev/null
-#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
+++ /dev/null
-/**
- * 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
+++ /dev/null
-#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
+++ /dev/null
-/**
- * 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
* 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_
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_
/**
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);
}
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;
}
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) {
*
* 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" {
} // extern "C"
#endif
-#endif // _fss_identify_print_data_data_h
+#endif // _fss_identify_print_data_h
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);
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);
* 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.
* 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.
*/
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) {
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) {
* 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_
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_
/**
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);
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);
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);
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) {
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.");
* 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_
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_
/**
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);
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) {
* 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_
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_
/**
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);
}
* 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.
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) {
* 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_
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_
/**
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);
}
* 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.
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) {
* 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_
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_
/**
* 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.
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);
}
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) {
* 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_
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_
/**
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);
}
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);
}
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);
* 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.
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) {
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);
}
}
}
- 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_