]> Kevux Git Server - fll/commitdiff
Progress: Continue refactoring firewall from 0.6.x to 0.7.x/0.8.x.
authorKevin Day <kevin@kevux.org>
Thu, 15 Feb 2024 04:25:53 +0000 (22:25 -0600)
committerKevin Day <kevin@kevux.org>
Thu, 15 Feb 2024 04:25:53 +0000 (22:25 -0600)
This is very close to be ready for review and testing.
I converted most of the buffers into the new structure but I need to check for isolation.
I am pretty sure that there are currently some isolation problems with the FSS Object and Content ranges.

I also noticed some typos and such that will need to be fixed (this therefore probably does not compile just yet).

29 files changed:
level_3/firewall/c/main/common/enumeration.h
level_3/firewall/c/main/common/print.c
level_3/firewall/c/main/common/print.h
level_3/firewall/c/main/common/type.c
level_3/firewall/c/main/common/type.h
level_3/firewall/c/main/firewall.h
level_3/firewall/c/main/operate.c
level_3/firewall/c/main/operate.h
level_3/firewall/c/main/operate/buffer.c
level_3/firewall/c/main/operate/buffer.h
level_3/firewall/c/main/operate/create.c
level_3/firewall/c/main/operate/create.h
level_3/firewall/c/main/operate/default.c
level_3/firewall/c/main/operate/default.h
level_3/firewall/c/main/operate/delete.c
level_3/firewall/c/main/operate/delete.h
level_3/firewall/c/main/operate/load.c
level_3/firewall/c/main/operate/load.h
level_3/firewall/c/main/operate/process.c
level_3/firewall/c/main/operate/process.h
level_3/firewall/c/main/print/data.c [deleted file]
level_3/firewall/c/main/print/data.h [deleted file]
level_3/firewall/c/main/print/error.c
level_3/firewall/c/main/print/error.h
level_3/firewall/c/main/print/verbose.c [deleted file]
level_3/firewall/c/main/print/verbose.h [deleted file]
level_3/firewall/c/main/print/warning.c
level_3/firewall/c/main/print/warning.h
level_3/firewall/data/build/settings

index d04d62fb42cdf42cc94156cf96b7c805a8804fa8..986d30c939e9a8deaa166f921fbc45678c2edc03 100644 (file)
@@ -69,65 +69,145 @@ extern "C" {
 #endif // _di_firewall_main_flag_e_
 
 /**
+ * The firewall action.
+ *
+ * firewall_action_*_e:
+ *   - none:   The action is none.
+ *   - append: The action is append.
+ *   - insert: The action is insert.
+ *   - policy: The action is policy.
+ */
+#ifndef _di_firewall_action_e_
+  enum {
+    firewall_action_none_e,
+    firewall_action_append_e,
+    firewall_action_insert_e,
+    firewall_action_policy_e,
+  }; // enum
+#endif // _di_firewall_action_e_
+
+/**
+ * The firewall chain.
+ *
+ * firewall_chain_*_e:
+ *   - none:        The chain is none.
+ *   - forward:     The chain is forward.
+ *   - input:       The chain is input.
+ *   - output:      The chain is output.
+ *   - postrouting: The chain is postrouting.
+ *   - prerouting:  The chain is prerouting.
+ */
+#ifndef _di_firewall_action_e_
+  enum {
+    firewall_chain_none_e,
+    firewall_chain_forward_e,
+    firewall_chain_input_e,
+    firewall_chain_output_e,
+    firewall_chain_postrouting_e,
+    firewall_chain_prerouting_e,
+  }; // enum
+#endif // _di_firewall_action_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.
+ * firewall_data_is_*_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.
+ *   - stop_main_lock: Helper flag representing main, stop, and lock being set.
  */
-#ifndef _di_firewall_data_flag_e_
+#ifndef _di_firewall_data_is_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,
+    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,
+    firewall_data_is_stop_main_lock_e = 0xe,
   }; // enum
-#endif // _di_firewall_data_flag_e_
+#endif // _di_firewall_data_is_e_
 
 /**
  * Flags representing the existence of reserved sets.
  *
- * firewall_data_flag_*_e:
+ * firewall_data_has_*_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_
+#ifndef _di_firewall_data_has_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_has_e_
+
+/**
+ * The firewall direction.
+ *
+ * firewall_direction_*_e:
+ *   - none:   No direction.
+ *   - input:  The input direction.
+ *   - output: The output direction.
+ */
+#ifndef _di_firewall_direction_e_
+  enum {
+    firewall_direction_none_e = 0,
+    firewall_direction_input_e,
+    firewall_direction_output_e,
+  }; // enum
+#endif // _di_firewall_direction_e_
+
+/**
+ * The firewall tool (the program being used).
+ *
+ * firewall_tool_*_e:
+ *   - none:       No flags set.
+ *   - ip46tables: Use both iptables and ip6tables tools.
+ *   - ip6tables:  Use the ip6tables tool.
+ *   - ipset:      Use the ipset tool.
+ *   - iptables:   Use the iptables tool.
+ */
+#ifndef _di_firewall_tool_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,
+    firewall_tool_none_e = 0,
+    firewall_tool_ip46tables_e,
+    firewall_tool_ip6tables_e,
+    firewall_tool_iptables_e,
+    firewall_tool_ipset_e,
   }; // enum
-#endif // _di_firewall_data_flag_e_
+#endif // _di_firewall_tool_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,
+    fake_parameter_operation_lock_e = f_console_standard_parameter_last_e,
+    fake_parameter_operation_restart_e,
+    fake_parameter_operation_show_e,
+    fake_parameter_operation_start_e,
+    fake_parameter_operation_stop_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), \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_lock_s,    0, f_console_flag_simple_e), \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_restart_s, 0, f_console_flag_simple_e), \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_show_s,    0, f_console_flag_simple_e), \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_start_s,   0, f_console_flag_simple_e), \
+      macro_f_console_parameter_t_initialize_6(fake_other_operation_stop_s,    0, f_console_flag_simple_e), \
     }
 
-  #define firewall_parameter_total_d (f_console_parameter_state_type_total_d + 4)
+  #define firewall_parameter_total_d (f_console_parameter_state_type_total_d + 5)
 #endif // _di_firewall_parameter_e_
 
 /**
index 0567f9f13052bdcf99f5917336cfa3cc2d3d8e2d..b50759837d7d70b5d8e3554d567b672543d12b7b 100644 (file)
@@ -8,8 +8,17 @@ extern "C" {
   const f_string_t firewall_f_a[] = {
     "f_console_parameter_process",
     "f_directory_list",
+    "f_file_open",
+    "f_file_read",
     "f_fss_apply_delimit",
-    "firewall_operate_process_rules_perform",
+    "f_memory_array_increase",
+    "f_memory_array_increase_by",
+    "f_string_dynamic_append",
+    "f_string_dynamic_partial_append",
+    "firewall_operate_process_rules",
+    "fll_execute_program",
+    "fll_fss_basic_read",
+    "fll_fss_basic_list_read",
     "fll_fss_extended_read",
     "fll_program_parameter_process_context_standard",
     "fll_program_parameter_process_verbosity_standard",
index 85b7a87e86816102c49f9a599fe4d52f22bd93e1..b57d6f0818b402eebe7d466b9525682044af5399 100644 (file)
@@ -41,8 +41,17 @@ extern "C" {
   enum {
     firewall_f_f_console_parameter_process_e,
     firewall_f_f_directory_list_e,
+    firewall_f_f_file_open_e,
+    firewall_f_f_file_read_e,
     firewall_f_f_fss_apply_delimit_e,
+    firewall_f_f_memory_array_increase_e,
+    firewall_f_f_memory_array_increase_by_e,
+    firewall_f_f_string_dynamic_append_e,
+    firewall_f_f_string_dynamic_partial_append_e,
     firewall_f_firewall_operate_process_rules_perform_e,
+    firewall_f_fll_execute_program_e,
+    firewall_f_fll_fss_basic_read_e,
+    firewall_f_fll_fss_basic_list_read_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,
index 21bea932277e48a91d8ba50335686fc1db0fe1e3..0a6da2b4120ab94c162fb5269282db1dcc165980 100644 (file)
@@ -4,6 +4,28 @@
 extern "C" {
 #endif
 
+#ifndef _di_firewall_cache_delete_
+  void firewall_cache_delete(firewall_cache_t * const cache) {
+
+    if (!cache) return;
+
+    f_file_close(&cache->file);
+
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->buffer.string, &cache->buffer.used, &cache->buffer.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->device.string, &cache->device.used, &cache->device.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->ip_list.string, &cache->ip_list.used, &cache->ip_list.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->local_buffer.string, &cache->local_buffer.used, &cache->local_buffer.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->path_file.string, &cache->path_file.used, &cache->path_file.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->path_file_specific.string, &cache->path_file_specific.used, &cache->path_file_specific.size);
+    f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->protocol.string, &cache->protocol.used, &cache->protocol.size);
+
+    f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &cache->arguments.array, &cache->arguments.used, &cache->arguments.size, &f_string_dynamics_delete_callback);
+
+    f_memory_array_resize(0, sizeof(f_range_t), (void **) &cache->basic_objects.string, &cache->basic_objects.used, &cache->basic_objects.size);
+    f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &cache->basic_contents.array, &cache->basic_contents.used, &cache->basic_contents.size, &f_rangess_delete_callback);
+  }
+#endif // _di_firewall_cache_delete_
+
 #ifndef _di_firewall_data_delete_
   void firewall_data_delete(firewall_data_t * const data) {
 
@@ -26,8 +48,10 @@ extern "C" {
     if (!main) return;
 
     fll_program_data_delete(&main->program);
+
     firewall_setting_delete(&main->setting);
     firewall_data_delete(&main->data);
+    firewall_cache_delete(&main->cache);
   }
 #endif // _di_firewall_main_delete_
 
index ff541db8ee83f98f37d1203e0d03b279e61010f9..a300a8d71db731179a87bdd87ac92fe8284e7714 100644 (file)
@@ -17,12 +17,64 @@ extern "C" {
 #endif
 
 /**
- * A data uses for building and processing firewall rules.
+ * A cache used for during processing.
+ *
+ * Properties:
+ *   - file: The file structure.
+ *
+ *   - buffer:             A generic string buffer.
+ *   - device:             The device string.
+ *   - ip_list:            The ip_list string.
+ *   - local_buffer:       The protocol string.
+ *   - path_file:          The protocol string.
+ *   - path_file_specific: The protocol string.
+ *   - protocol:           The protocol string.
+ *   - arguments:          The array of strings.
+ *
+ *   - basic_objects:  The FSS Basic Objects.
+ *   - basic_contents: The FSS Basic Contents.
+ */
+#ifndef _di_firewall_cache_t_
+  typedef struct {
+    f_file_t file = f_file_t_initialize;
+
+    f_string_dynamic_t buffer;
+    f_string_dynamic_t device;
+    f_string_dynamic_t ip_list;
+    f_string_dynamic_t local_buffer;
+    f_string_dynamic_t path_file;
+    f_string_dynamic_t path_file_specific;
+    f_string_dynamic_t protocol;
+    f_string_dynamics_t arguments;
+
+    f_ranges_t basic_objects;
+    f_rangess_t basic_contents;
+  } firewall_cache_t;
+
+  #define firewall_cache_t_initialize \
+    { \
+      f_file_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_dynamics_t_initialize, \
+      f_ranges_t_initialize, \
+      f_rangess_t_initialize, \
+    }
+#endif // _di_firewall_cache_t_
+
+/**
+ * A data used 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.
  *
+ *   - chain:  The chain currently being processed (fom chain_contents).
  *   - device: The device position.
  *   - lock:   The lock position.
  *   - main:   The main position.
@@ -44,6 +96,7 @@ extern "C" {
     uint8_t is;
     uint8_t has;
 
+    f_number_unsigned_t chain;
     f_number_unsigned_t device;
     f_number_unsigned_t lock;
     f_number_unsigned_t main;
@@ -69,6 +122,7 @@ extern "C" {
       0, \
       0, \
       0, \
+      0, \
       f_range_t_initialize, \
       f_number_unsigneds_t_initialize, \
       f_number_unsigneds_t_initialize, \
@@ -123,12 +177,14 @@ extern "C" {
  *   - program: The main program data.
  *   - setting: The settings data.
  *   - data:    The firewall data.
+ *   - cache:   The firewall cache.
  */
 #ifndef _di_firewall_main_t_
   typedef struct {
     fll_program_data_t program;
     firewall_setting_t setting;
     firewall_data_t data;
+    firewall_cache_t cache;
   } firewall_main_t;
 
   #define firewall_main_t_initialize \
@@ -136,10 +192,23 @@ extern "C" {
       fll_program_data_t_initialize, \
       firewall_setting_t_initialize, \
       firewall_data_t_initialize, \
+      firewall_cache_t_initialize, \
     }
 #endif // _di_firewall_main_t_
 
 /**
+ * Deallocate firewall cache.
+ *
+ * @param cache
+ *   The firewall cache.
+ *
+ *   This does not alter main.setting.state.status.
+ */
+#ifndef _di_firewall_cache_delete_
+  extern void firewall_data_delete(firewall_cache_t * const cache);
+#endif // _di_firewall_cache_delete_
+
+/**
  * Deallocate firewall data.
  *
  * @param data
index 445b8c9e966cb7c2128cced4a54a56eca4a650eb..13ac460968c04c8c16bd47e6338e0542638b6755 100644 (file)
 #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>
index e1303fdbc4065fc16336606f8c6b86534ee247ac..d541f1fff82e6ea3ed1bf80df2e74e93fc286611 100644 (file)
@@ -12,99 +12,7 @@ extern "C" {
     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
+      firewall_operate_show(main);
 
       return;
     }
@@ -129,16 +37,18 @@ extern "C" {
     f_string_static_t buffer = f_string_static_t_initialize;
 
     // Remove "lo" (loopback) from the device listing.
-    for (; i < data.devices.used; ++i) {
+    for (; i < main->data.devices.used; ++i) {
+
+      if (firewall_signal_check(main)) return;
 
-      if (f_compare_dynamic(firewall_device_loop_s, data.devices.array[i]) == F_equal_to) {
-        buffer = data.devices.array[i];
+      if (f_compare_dynamic(firewall_device_loop_s, main->data.devices.array[i]) == F_equal_to) {
+        buffer = main->data.devices.array[i];
 
-        for (--data.devices.used; i < data.devices.used; ++i) {
-          data.devices.array[i] = data.devices.array[i + 1];
+        for (--main->data.devices.used; i < main->data.devices.used; ++i) {
+          main->data.devices.array[i] = main->data.devices.array[i + 1];
         } // for
 
-        data.devices.array[data.devices.used] = buffer;
+        main->data.devices.array[main->data.devices.used] = buffer;
       }
     } // for
 
@@ -147,7 +57,7 @@ extern "C" {
 
       f_char_t path_file_other[buffer.used + 1];
       buffer.string = path_file_other;
-      buffer[buffer.used] = 0;
+      path_file_other[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);
@@ -157,6 +67,8 @@ extern "C" {
 
       for (i = 0; i < main->data.chain_objects.used; ++i) {
 
+        if (firewall_signal_check(main)) return;
+
         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;
@@ -171,19 +83,16 @@ extern "C" {
         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);
-          }
+          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.chain = main->data.lock;
           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;
+          main->data.range.start = main->data.chain_contents.array[main->data.lock].array[0].start;
+          main->data.range.stop = main->data.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);
@@ -198,20 +107,14 @@ extern "C" {
         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);
-          }
+          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;
+          main->data.chain = main->data.stop;
+          main->data.is = firewall_data_is_global_e | firewall_data_is_stop_e;
+          main->data.range.start = main->data.chain_contents.array[main->data.stop].array[0].start;
+          main->data.range.stop = main->data.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;
@@ -226,240 +129,203 @@ extern "C" {
       }
     }
 
-    /*
     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;
+      buffer.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;
+      f_char_t path_file_first[buffer.used + 1];
+      buffer.string = path_file_first_string;
+      path_file_first[buffer.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);
+      memcpy(path_file_first, firewall_network_path_s.string, sizeof(f_char_t) * firewall_network_path_s.used);
+      memcpy(path_file_first + 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);
+      firewall_operate_buffer_rules(main, buffer, F_false);
 
-      if (F_status_is_error(status) || status == F_child) {
-        firewall_delete_local_data(&local);
-        firewall_data_delete(&data);
+      if (main->setting.flag & firewall_main_flag_operation_start_e) {
+        firewall_operate_delete_chains(main);
 
-        return status;
+        firewall_operate_default_lock(main);
       }
 
-      if (command == firewall_parameter_command_start_e) {
-        status = firewall_operate_delete_chains(&data);
+      firewall_operate_create_custom_chains(main);
 
-        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;
-        }
-      }
+      main->data.is = firewall_data_is_global_e;
 
-      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);
+      firewall_operate_load_chains(main);
+      if (F_status_is_error(main->setting.state.status) || main->setting.state.status == F_child || (main->setting.flag & firewall_main_flag_operation_stop_e)) return;
 
       {
-        f_string_dynamic_t path_file = f_string_dynamic_t_initialize;
-        f_number_unsigned_t j = 0;
+        for (f_number_unsigned_t j = 0; j < main->data.devices.used; ++j) {
 
-        for (i = 0; i < data.devices.used; ++i) {
+          if (firewall_signal_check(main)) return;
 
-          path_file.used = 0;
-          local.device = i;
+          main->data.path_file.used = 0;
+          local.device = j;
 
-          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);
+          main->setting.state.status = f_memory_array_increase_by(firewall_network_path_s.used + data.devices.array[j].used + firewall_file_suffix_s.used + 1, sizeof(f_char_t), (void **) &main->data.path_file.string, &main->data.path_file.used, &main->data.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(main->setting.state.status)) {
+            firewall_print_error(&main->program.error, macro_firewall_f(f_memory_array_increase_by));
 
-          if (F_status_is_error_not(status)) {
-            status = f_string_dynamic_append(data.devices.array[i], &path_file);
+            return;
           }
 
-          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);
+          main->setting.state.status = f_string_dynamic_append(firewall_network_path_s, &main->data.path_file);
 
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
+          if (F_status_is_error_not(main->setting.state.status)) {
+            main->setting.state.status = f_string_dynamic_append(data.devices.array[j], &main->data.path_file);
           }
 
-          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);
+          if (F_status_is_error_not(main->setting.state.status)) {
+            main->setting.state.status = f_string_dynamic_append(firewall_file_suffix_s, &main->data.path_file);
           }
 
-          status = firewall_operate_create_custom_chains(&data, &reserved, &local);
+          if (F_status_is_error(main->setting.state.status)) {
+            firewall_print_error(&main->program.error, macro_firewall_f(f_string_dynamic_append));
 
-          if (F_status_is_error(status) || status == F_child) {
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
-
-            return status;
+            return;
           }
 
-          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);
+          firewall_operate_buffer_rules(main, main->data.path_file, F_true);
 
-            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_operate_create_custom_chains(main);
 
-              firewall_delete_local_data(&local);
-              firewall_data_delete(&data);
+          main->data.is = 0;
 
-              return status;
-            }
-          } // for
-
-          firewall_delete_local_data(&local);
+          firewall_operate_load_chains(main);
+          if (F_status_is_error(main->setting.state.status) || main->setting.state.status == F_child || (main->setting.flag & firewall_main_flag_operation_stop_e)) return;
         } // for
 
-        path_file.used = 0;
-
-        status = f_string_dynamic_append(firewall_network_path_s, &path_file);
+        main->data.path_file.used = 0;
 
-        if (F_status_is_error_not(status)) {
-          status = f_string_dynamic_append(firewall_file_last_s, &path_file);
-        }
+        main->setting.state.status = f_string_dynamic_append(firewall_network_path_s, &main->data.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_not(main->setting.state.status)) {
+          main->setting.state.status = f_string_dynamic_append(firewall_file_last_s, &main->data.path_file);
         }
 
-        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);
+        if (F_status_is_error(main->setting.state.status)) {
+          firewall_print_error(&main->program.error, macro_firewall_f(f_string_dynamic_append));
 
-          return status;
+          return;
         }
 
-        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;
-        }
+        firewall_operate_buffer_rules(main, main->data.path_file, F_false);
 
-        i = 0;
+        firewall_operate_create_custom_chains(main);
 
-        local.is_global = F_true;
-        local.is_stop = F_false;
-        local.is_lock = F_false;
+        main->data.is = firewall_data_is_global_e;
 
-        while (i < local.chain_contents.used) {
+        firewall_operate_load_chains(main);
+        if (F_status_is_error(main->setting.state.status) || main->setting.state.status == F_child) return;
+      }
+    }
 
-          input.start = local.chain_contents.array[i].array[0].start;
-          input.stop = local.chain_contents.array[i].array[0].stop;
+    main->setting.state.status = F_okay;
+  }
+#endif // _di_firewall_operate_
 
-          local.is_main = reserved.has_main && i == main->data.main ? F_true : F_false;
-          local.chain = i;
+#ifndef _di_firewall_operate_show_
+  void firewall_operate_show(firewall_main_t * const main) {
 
-          status = firewall_operate_load_rules(&data, &input, &local);
+    if (!main) return;
 
-          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);
+    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;
 
-            firewall_delete_local_data(&local);
-            firewall_data_delete(&data);
+        return;
+      }
 
-            return status;
-          }
+      fll_print_dynamic_raw(f_string_eol_s, main->output.to);
+      f_file_stream_flush(main->output.to);
 
-          ++i;
-        } // while
+      if (F_status_is_error(main->setting.status)) {
+        firewall_print_error_operation(&main->error, firewall_tool_iptables_s, parameters);
 
-        f_memory_array_resize(0, sizeof(f_char_t), (void **) &path_file.string, &path_file.used, &path_file.size);
+        return;
       }
-    }
-    */
+    } // for
+
+    main->setting.state.status = F_okay;
   }
-#endif // _di_firewall_operate_
+#endif // _di_firewall_operate_show_
 
 #ifdef __cplusplus
 } // extern "C"
index ea54ede56cc1868193385ffbec16a5fe093bf0d8..331b44072c53e90f24f1fb47414b123623fa7eac 100644 (file)
@@ -24,17 +24,56 @@ extern "C" {
  *
  *   This alters main.setting.state.status:
  *     F_okay on success.
+ *     F_child on child process exiting.
  *
  *     F_interrupt (with error bit) on interrupt signal received.
  *
- *     Errors (with error bit) from: ()
+ *     Errors (with error bit) from: f_directory_list()
+ *     Errors (with error bit) from: f_memory_array_increase_by()
+ *     Errors (with error bit) from: firewall_operate_buffer_rules()
+ *     Errors (with error bit) from: firewall_operate_create_custom_chains()
+ *     Errors (with error bit) from: firewall_operate_default_lock()
+ *     Errors (with error bit) from: firewall_operate_delete_chains()
+ *     Errors (with error bit) from: firewall_operate_load_rules()
+ *     Errors (with error bit) from: firewall_operate_process_rules()
+ *     Errors (with error bit) from: firewall_operate_show()
  *
- * @see ()
+ * @see f_directory_list()
+ * @see f_memory_array_increase_by()
+ * @see firewall_operate_buffer_rules()
+ * @see firewall_operate_create_custom_chains()
+ * @see firewall_operate_default_lock()
+ * @see firewall_operate_delete_chains()
+ * @see firewall_operate_load_rules()
+ * @see firewall_operate_process_rules()
+ * @see firewall_operate_show()
  */
 #ifndef _di_firewall_operate_
   extern void firewall_operate(firewall_main_t * const main);
 #endif // _di_firewall_operate_
 
+/**
+ * Perform the firewall show operation.
+ *
+ * @param main
+ *   The main program and setting data.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *     F_child on child process exiting.
+ *
+ *     F_interrupt (with error bit) on interrupt signal received.
+ *
+ *     Errors (with error bit) from: fll_execute_program()
+ *     Errors (with error bit) from: fll_print_dynamic_raw()
+ *
+ * @see fll_execute_program()
+ * @see fll_print_dynamic_raw()
+ */
+#ifndef _di_firewall_operate_show_
+  extern void firewall_operate_show(firewall_main_t * const main);
+#endif // _di_firewall_operate_show_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 2544b42fba3893fed74872d4f2a45c0854d4d875..1befc0deef45b0c67595ae2f6dc7361e3b5e9e6e 100644 (file)
@@ -5,118 +5,62 @@ 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));
-          }
-        }
-      }
+  void firewall_operate_buffer_rules(firewall_main_t * const main, const f_string_static_t file, const bool optional) {
 
-      return status;
-    }
+    if (!main || F_status_is_error_not(main->setting.state.status) && main->setting.state.status == F_child) return;
 
-    status = f_file_read(file, &local->buffer);
+    main->data.buffer.used = 0;
 
-    f_file_stream_flush(file);
-    f_file_stream_close(&file);
+    main->setting.state.status = f_file_open(file, 0, &main->cache.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));
-        }
-      }
+    if (F_status_is_error(main->setting.state.status)) {
+      if (!optional || optional && F_status_set_fine(main->setting.state.status) != F_file_found_not && F_status_set_fine(main->setting.state.status) != F_file_open && F_status_set_fine(main->setting.state.status) != F_file_descriptor) {
+        firewall_print_error_file(&main->program.error, macro_firewall_f(f_file_open), f_file_operation_open_s, fll_error_file_type_file_e);
 
-      return status;
+        return;
+      }
     }
 
-    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;
+    main->setting.state.status = f_file_read(main->cache.file, &main->data.buffer);
+
+    f_file_stream_flush(main->cache.file);
+    f_file_stream_close(&main->cache.file);
 
-    {
-      f_range_t input = macro_f_range_t_initialize_2(local->buffer.used);
+    if (F_status_is_error(main->setting.state.status)) {
+      firewall_print_error_file(&main->program.error, macro_firewall_f(f_file_read), f_file_operation_read_s, fll_error_file_type_file_e);
 
-      status = fll_fss_basic_list_read(local->buffer, state, &input, &local->chain_objects, &local->chain_contents, &delimits, 0, &comments);
+      return;
     }
 
-    if (F_status_is_error(status)) {
-      status = F_status_set_fine(status);
+    if (main->data.buffer.used) {
+      main->data.range.start = 0;
+      main->data.range.stop = main->data.buffer.used - 1;
 
-      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);
+// @fixme bufferchain_objects, etc..
+      main->setting.state.status = fll_fss_basic_list_read(main->data.buffer, main->setting.state, &main->data.range, &main->data.bufferchain_objects, &main->data.bufferchain_contents, &main->data.delimits, 0, &main->data.comments);
+
+      if (F_status_is_error(main->setting.state.status)) {
+        if (F_status_set_fine(main->setting.state.status) == F_data_not_eos || F_status_set_fine(main->setting.state.status) == F_data_not || F_status_set_fine(main->setting.state.status) == F_data_not_stop) {
+          firewall_print_error_file_empty(&main->program.error, file);
         }
         else {
-          firewall_print_error_on_unhandled_for_file(data->main->error, "fll_fss_basic_read", status, filename);
+          firewall_print_error_file(&main->program.error, macro_firewall_f(fll_fss_basic_list_read), f_file_operation_process_s, fll_error_file_type_file_e);
         }
+
+        return;
       }
-    }
-    else {
-      status = f_fss_apply_delimit(state, delimits, &local->buffer);
+      else {
+        main->setting.state.status = f_fss_apply_delimit(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));
 
-      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);
+          return;
+        }
       }
     }
 
-    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;
+    main->setting.state.status = F_okay;
   }
 #endif // _di_firewall_operate_buffer_rules_
 
index ec4e9af9bfbc83a33a8814649b4c0d43029c3ce8..4a43f623537e08420412fe3b63a351c7b83dbf23 100644 (file)
@@ -19,24 +19,32 @@ extern "C" {
 /**
  * Buffer firewall rules.
  *
- * @param data
- *   The program data.
- * @param filename
+ * @param main
+ *   The main program and setting data.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *     F_child on child process exiting.
+ *
+ *     F_interrupt (with error bit) on interrupt signal received.
+ *
+ *     Errors (with error bit) from: f_file_open()
+ *     Errors (with error bit) from: f_file_read()
+ *     Errors (with error bit) from: f_fss_apply_delimit()
+ *     Errors (with error bit) from: fll_fss_basic_list_read()
+ * @param file
  *   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.
+ * @see f_file_open()
+ * @see f_file_read()
+ * @see f_fss_apply_delimit()
+ * @see fll_fss_basic_list_read()
  */
 #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);
+  extern void firewall_operate_buffer_rules(firewall_main_t * const main, const f_string_static_t file, const bool optional);
 #endif // _di_firewall_operate_buffer_rules_
 
 #ifdef __cplusplus
index 0624b229de9f4b567a915290f75930e4f20b4cc8..d7d563705302dba90d49c0a3b7ae700e42123200 100644 (file)
@@ -5,91 +5,96 @@ extern "C" {
 #endif
 
 #ifndef _di_firewall_operate_create_custom_chains_
-  f_status_t firewall_operate_create_custom_chains(firewall_main_t * const main) {
+  void firewall_operate_create_custom_chains(firewall_main_t * const main) {
 
-    if (!main) return F_status_set_error(F_parameter);
+    if (!main || F_status_is_error_not(main->setting.state.status) && main->setting.state.status == F_child) return;
 
-    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;
 
+    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;
+    f_string_static_t tool = firewall_tool_iptables_s;
 
-    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;
+    main->cache.chain_ids.used = 0;
+    main->cache.arguments.used = 0;
 
-    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;
+    main->setting.state.status = f_memory_array_increase_by(2, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
 
-    memset(local->chain_ids.array, 0, sizeof(f_number_unsigned_t) * local->chain_ids.used);
+    if (F_status_is_error_not(main->setting.state.status)) {
+      main->setting.state.status = f_memory_array_increase_by(main->cache.chain_objects.used, sizeof(f_number_unsigned_t), (void **) &main->cache.chain_ids.array, &main->cache.chain_ids.used, &main->cache.chain_ids.size);
+    }
 
-    status = f_string_dynamic_append(firewall_chain_create_command_s, &arguments.array[0]);
+    if (F_status_is_error(main->setting.state.status)) {
+      firewall_print_error(&main->program.error, macro_firewall_f(f_memory_array_increase_by));
 
-    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);
+      return;
     }
-    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;
+    main->cache.chain_ids.used = main->cache.chain_objects.used;
+    memset(main->cache.chain_ids.array, 0, sizeof(f_number_unsigned_t) * main->cache.chain_ids.used);
+
+    main->setting.state.status = f_string_dynamic_append(firewall_chain_create_command_s, &main->cache.arguments.array[0]);
+
+    if (F_status_is_error(main->setting.state.status)) {
+      firewall_print_error(&main->program.error, macro_firewall_f(f_string_dynamic_append));
+
+      return;
     }
 
-    arguments.used = 2;
+    main->setting.state.status = f_memory_array_increase(F_memory_default_allocation_small_d, sizeof(f_char_t), (void **) &main->cache.arguments.array[1].string, &main->cache.arguments.array[1].used, &main->cache.arguments.array[1].size);
 
-    reserved->has_lock = F_false;
-    reserved->has_stop = F_false;
-    reserved->has_main = F_false;
+    if (F_status_is_error(main->setting.state.status)) {
+      firewall_print_error(&main->program.error, macro_firewall_f(f_memory_array_increase));
 
-    for (; i < local->chain_objects.used; ++i) {
+      return;
+    }
+
+    main->cache.arguments.used = 2;
+    main->data.has = 0;
+
+    for (; i < main->cache.chain_objects.used; ++i) {
+
+      if (firewall_signal_check(main)) return;
 
       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) {
+      if (f_compare_dynamic_partial_string(firewall_group_main_s.string, main->cache.buffer, firewall_group_main_s.used, main->cache.chain_objects.array[i]) == F_equal_to) {
         new_chain = F_false;
-        reserved->has_main = F_true;
-        reserved->main_at = i;
+        main->data.has |= firewall_data_has_main_e;
+        main->data.main = 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) {
+      if (f_compare_dynamic_partial_string(firewall_group_stop_s.string, main->cache.buffer, firewall_group_stop_s.used, main->cache.chain_objects.array[i]) == F_equal_to) {
         new_chain = F_false;
-        reserved->has_stop = F_true;
-        reserved->stop_at = i;
+        main->data.has |= firewall_data_has_stop_e;
+        main->data.stop = 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) {
+      if (f_compare_dynamic_partial_string(firewall_group_lock_s.string, main->cache.buffer, firewall_group_lock_s.used, main->cache.chain_objects.array[i]) == F_equal_to) {
         new_chain = F_false;
-        reserved->has_lock = F_true;
-        reserved->lock_at = i;
+        main->data.has |= firewall_data_has_lock_e;
+        main->data.lock = 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) {
+      if (f_compare_dynamic_partial_string(firewall_chain_none_s.string, main->cache.buffer, firewall_chain_none_s.used, main->cache.chain_objects.array[i]) == F_equal_to) {
         new_chain = F_false;
       }
 
       if (new_chain) {
-        for (; j < data->chains.used; ++j) {
+        for (; j < main->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) {
+          if (f_compare_dynamic_partial_string(main->data.chains.array[j].string, main->cache.buffer, main->data.chains.array[j].used, main->cache.chain_objects.array[i]) == F_equal_to) {
             new_chain = F_false;
-            local->chain_ids.array[i] = j;
+            main->cache.chain_ids.array[i] = j;
 
             break;
           }
@@ -97,104 +102,110 @@ extern "C" {
       }
 
       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;
+        main->setting.state.status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &main->data.chains.array, &main->data.chains.used, &main->data.chains.size);
+
+        if (F_status_is_error(main->setting.state.status)) {
+          firewall_print_error(&main->program.error, macro_firewall_f(f_memory_array_increase));
+
+          return;
+        }
 
         create_chain = F_true;
-        length = (local->chain_objects.array[i].stop - local->chain_objects.array[i].start) + 1;
+        length = (main->data.chain_objects.array[i].stop - main->data.chain_objects.array[i].start) + 1;
+
+        main->cache.arguments.array[1].used = 0;
+
+        main->setting.state.status = f_memory_array_increase_by(length + 1, sizeof(f_char_t), (void **) &main->cache.arguments.array[1].string, &main->cache.arguments.array[1].used, &main->cache.arguments.array[1].size);
 
-        arguments.array[1].used = 0;
+        if (F_status_is_error_not(main->setting.state.status)) {
+          main->setting.state.status = f_memory_array_increase_by(length + 1, sizeof(f_char_t), (void **) &main->data.chains.array[main->data.chains.used].string, &main->data.chains.array[main->data.chains.used].used, &main->data.chains.array[main->data.chains.used].size);
+        }
 
-        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;
+        if (F_status_is_error(main->setting.state.status)) {
+          firewall_print_error(&main->program.error, macro_firewall_f(f_memory_array_increase_by));
 
-        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;
+          return;
+        }
 
-        data->chains.array[data->chains.used].used = 0;
-        local->chain_ids.array[i] = data->chains.used;
+        main->data.chains.array[main->data.chains.used].used = 0;
+        main->data.chain_ids.array[i] = main->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) {
+        for (j = main->data.chain_objects.array[i].start; j <= main->data.chain_objects.array[i].stop; ++j) {
 
-          if (local->buffer.string[j] == f_fss_placeholder_s.string[0]) continue;
+          if (main->data.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];
+          main->data.chains.array[main->data.chains.used].string[main->data.chains.array[main->data.chains.used].used++] = main->data.buffer.string[j];
+          main->cache.arguments.array[1].string[main->cache.arguments.array[1].used++] = main->data.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;
+        main->cache.arguments.array[1].string[main->cache.arguments.array[1].used] = 0;
+        main->data.chains.array[main->data.chains.used].string[main->data.chains.array[main->data.chains.used].used] = 0;
 
-        if (f_compare_dynamic(arguments.array[1], firewall_chain_forward_s) == F_equal_to) {
+        if (f_compare_dynamic(main->cache.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) {
+        else if (f_compare_dynamic(main->cache.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) {
+        else if (f_compare_dynamic(main->cache.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) {
+        else if (f_compare_dynamic(main->cache.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) {
+        else if (f_compare_dynamic(main->cache.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);
+          firewall_print_debug_tool(main->program->warning, firewall_tool_iptables_s, main->cache.arguments);
 
-          tool = firewall_program_iptables_e;
-          status = fll_execute_program(firewall_tool_iptables_s, arguments, 0, 0, (void *) &return_code);
+          tool = firewall_tool_iptables_s;
 
-          if (status == F_child) {
-            data->main->child = return_code;
+          main->setting.state.status = fll_execute_program(firewall_tool_iptables_s, main->cache.arguments, 0, 0, (void *) &return_code);
 
-            break;
+          if (main->setting.state.status == F_child) {
+            main->program->child = return_code;
+
+            return;
           }
 
-          if (F_status_is_error_not(status)) {
-            if (firewall_signal_received(data)) {
-              status = F_status_set_error(F_interrupt);
+          if (firewall_signal_check(main)) return;
 
-              break;
-            }
+          if (F_status_is_error_not(main->setting.state.status) && main->setting.state.status != F_child) {
+            tool = firewall_tool_ip6tables_s;
 
-            firewall_print_debug_tool(data->main->warning, firewall_tool_ip6tables_s, arguments);
+            firewall_print_debug_tool(main->program->warning, firewall_tool_ip6tables_s, main->cache.arguments);
 
-            tool = firewall_program_ip6tables_e;
-            status = fll_execute_program(firewall_tool_ip6tables_s, arguments, 0, 0, (void *) &return_code);
+            main->setting.state.status = fll_execute_program(firewall_tool_ip6tables_s, main->cache.arguments, 0, 0, (void *) &return_code);
+          }
 
-            if (status == F_child) {
-              data->main->child = return_code;
+          if (main->setting.state.status == F_child) {
+            main->program->child = return_code;
 
-              break;
-            }
+            return;
           }
 
-          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");
+          if (firewall_signal_check(main)) return;
+
+          if (F_status_is_error(main->setting.state.status)) {
+            if (F_status_set_fine(main->setting.state.status) == F_failure) {
+              firewall_print_error_operation(main->program->error, tool, main->cache.arguments);
             }
             else {
-              firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
+              firewall_print_error(&main->program.error, macro_firewall_f(fll_execute_program));
             }
 
-            break;
+            return;
           }
         }
 
-        ++data->chains.used;
+        ++main->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;
+    main->setting.state.status = F_okay;
   }
 #endif // _di_firewall_operate_create_custom_chains_
 
index d3b845576e4d099b762291963e591a64152be228..4fedb4dce6fef111c7217473eec26e1f38972114 100644 (file)
@@ -17,26 +17,34 @@ extern "C" {
 #endif
 
 /**
- * Create custom chains.
+ * Apply firewall rules for creating custom chains.
  *
- * @param data
- *   The program data.
- * @param reserved
- *   firewall chains.
- * @param local
- *   Local firewall settings.
+ * @param main
+ *   The main program and setting data.
  *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
+ *   This alters main.setting.state.status:
+ *     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.
+ *     F_interrupt (with error bit) on interrupt signal received.
  *
- *   Status codes (with error bit) are returned on any problem.
+ *     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: fll_execute_program()
+ * @param file
+ *   File name to read the rules from.
+ * @param optional
+ *   TRUE if this files is optional.
+ *   FALSE otherwise (more are errors returned when not optional).
+ *
+ * @see f_memory_array_increase()
+ * @see f_memory_array_increase_by()
+ * @see f_string_dynamic_append()
+ * @see fll_execute_program()
  */
 #ifndef _di_firewall_operate_create_custom_chains_
-  extern f_status_t firewall_operate_create_custom_chains(firewall_main_t * const main);
+  extern void firewall_operate_create_custom_chains(firewall_main_t * const main);
 #endif / _di_firewall_operate_create_custom_chains_
 
 #ifdef __cplusplus
index 5b84d10799275e09f8e5df6780087b301e92fa33..0d46c9682538913ad5588e185046b5ddd76ef701 100644 (file)
@@ -5,17 +5,13 @@ extern "C" {
 #endif
 
 #ifndef _di_firewall_operate_default_lock_
-  f_status_t firewall_operate_default_lock(firewall_data_t * const data) {
+  void firewall_operate_default_lock(firewall_main_t * const main) {
 
-    if (!data) return F_status_set_error(F_parameter);
+    if (!main || F_status_is_error_not(main->setting.state.status) && main->setting.state.status == F_child) return;
 
     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;
 
@@ -24,8 +20,9 @@ extern "C" {
     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;
+    int return_code = 0;
+    uint8_t i = 0;
+    uint8_t j = 0;
 
     for (; i < 3; ++i) {
 
@@ -37,37 +34,30 @@ extern "C" {
 
         return_code = 0;
 
-        status = fll_execute_program(tools[j], arguments, 0, 0, (void *) &return_code);
+        main->setting.state.status = fll_execute_program(tools[j], arguments, 0, 0, (void *) &return_code);
 
-        if (status == F_child) {
+        if (main->setting.state.status == F_child) {
           data->main->child = return_code;
 
-          break;
+          return;
         }
 
-        if (firewall_signal_received(data)) {
-          status = F_status_set_error(F_interrupt);
+        if (firewall_signal_check(main)) return;
 
-          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");
+        if (F_status_is_error(main->setting.state.status)) {
+          if (F_status_set_fine(main->setting.state.status) == F_failure) {
+            firewall_print_error_operation(main->program->error, tools[j], arguments);
           }
           else {
-            firewall_print_error_on_unhandled(data->main->error, "fll_execute_program", F_status_set_fine(status));
+            firewall_print_error(&main->program.error, macro_firewall_f(fll_execute_program));
           }
 
-          break;
+          return;
         }
       } // for
     } // for
 
-    return status;
+    main->setting.state.status = F_okay;
   }
 #endif // _di_firewall_operate_default_lock_
 
index 5fb890eb9f119103a716c8e371ad1aab3ef3a1e9..41a7c5dff23fe2e8f3602da03ceb0ea18ebf4447 100644 (file)
@@ -17,19 +17,25 @@ extern "C" {
 #endif
 
 /**
- * Lock the firewall.
+ * Apply firewall rules intended to lock down the firewall.
  *
- * @param data
- *   The program data.
+ * This is intended to setup the firewall with rules that prevent access to or from the network.
  *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
+ * @param main
+ *   The main program and setting data.
  *
- *   Status codes (with error bit) are returned on any problem.
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *     F_child on child process exiting.
+ *
+ *     F_interrupt (with error bit) on interrupt signal received.
+ *
+ *     Errors (with error bit) from: fll_execute_program()
+ *
+ * @see fll_execute_program()
  */
 #ifndef _di_firewall_operate_default_lock_
-  extern f_status_t firewall_operate_default_lock(firewall_main_t * const main);
+  extern void firewall_operate_default_lock(firewall_main_t * const main);
 #endif // _di_firewall_operate_default_lock_
 
 #ifdef __cplusplus
index 95b72df3b8f9cb77d11b186928e7d89bad8e6727..03670e0be1e25419d504a2ae6b2221e776bb3c6a 100644 (file)
@@ -5,98 +5,58 @@ extern "C" {
 #endif
 
 #ifndef _di_firewall_operate_delete_chains_
-  f_status_t firewall_operate_delete_chains(firewall_main_t * const main) {
+  void firewall_operate_delete_chains(firewall_main_t * const main) {
 
-    if (!data) return F_status_set_error(F_parameter);
+    if (!main || F_status_is_error_not(main->setting.state.status) && main->setting.state.status == F_child) return;
 
     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;
+    const f_string_static_t command[2] = { firewall_chain_flush_command_s, firewall_chain_delete_command_s };
 
     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;
+    argument_array[0] = firewall_chain_flush_command_s;
 
-    for (f_number_unsigned_t i = 0; i < 2; ++i) {
+    int return_code = 0;
+    uint8_t i = 0;
+    uint8_t j = 0;
 
-      firewall_print_debug_tool(data->main->warning, tools[i], arguments);
+    for (i = 0; i < 2; ++i) {
 
-      return_code = 0;
+      argument_array[0] = command[i];
 
-      status = fll_execute_program(tools[i], arguments, 0, 0, (void *) &return_code);
+      for (j = 0; j < 2; ++j) {
 
-      if (status == F_child) {
-        data->main->child = return_code;
+        if (firewall_signal_check(main)) return;
 
-        break;
-      }
+        return_code = 0;
 
-      if (firewall_signal_received(data)) {
-        status = F_status_set_error(F_interrupt);
+        firewall_print_debug_tool(data->main->warning, tools[j], arguments);
 
-        break;
-      }
+        main->setting.state.status = fll_execute_program(tools[j], arguments, 0, 0, (void *) &return_code);
 
-      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));
+        if (main->setting.state.status == F_child) {
+          data->main->child = return_code;
+
+          return;
         }
 
-        break;
-      }
+        if (F_status_is_error(main->setting.state.status)) {
+          if (F_status_set_fine(main->setting.state.status) == F_failure) {
+            firewall_print_error_operation(main->program->error, tools[j], arguments);
+          }
+          else {
+            firewall_print_error(&main->program.error, macro_firewall_f(fll_execute_program));
+          }
+
+          return;
+        }
+      } // for
     } // for
 
-    return status;
+    main->setting.state.status = F_okay;
   }
 #endif // _di_firewall_operate_delete_chains_
 
index 2b0a8a1c371d49d155b97d1c0dbec0bc5a5d23d5..cac86c148b0c6d96896f482c02cfacd1eeb3a12c 100644 (file)
 extern "C" {
 #endif
 
-/**
- * Deallocate chains.
+ /**
+ * Unapply (remove) the firewall rules, deleting all existing firewall rules being used.
+ *
+ * This function is not about de-allocating memory.
+ * This function is not about modifying settings or files.
+ *
+ * @param main
+ *   The main program and setting data.
  *
- * @param data
- *   The program data.
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *     F_child on child process exiting.
  *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
+ *     F_interrupt (with error bit) on interrupt signal received.
  *
- *   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: fll_execute_program()
  *
- *   Status codes (with error bit) are returned on any problem.
+ * @see fll_execute_program()
  */
 #ifndef _di_firewall_operate_delete_chains_
-  extern f_status_t firewall_operate_delete_chains(firewall_main_t * const main);
+  extern void firewall_operate_delete_chains(firewall_main_t * const main);
 #endif // _di_firewall_operate_delete_chains_
 
 #ifdef __cplusplus
index 9e558deaf6fa64820cd85bc77e49bbb0c848ad04..0a7ebda20ec0fd1c2fdf0833156036dbd6b65dba 100644 (file)
@@ -4,16 +4,43 @@
 extern "C" {
 #endif
 
+#ifndef _di_firewall_operate_load_chains_
+  void firewall_operate_load_chains(firewall_main_t * const main) {
+
+    if (!main || F_status_is_error_not(main->setting.state.status) && main->setting.state.status == F_child) return;
+
+    for (i = 0; i < local.chain_contents.used; ++i) {
+
+      main->data.range = local.chain_contents.array[i].array[0];
+
+      if ((main->data.has & firewall_data_has_main_e) && i == main->data.main) {
+        main->data.is |= firewall_data_is_main_e;
+      }
+      else {
+        main->data.is &= ~firewall_data_is_main_e;
+      }
+
+      main->data.chain = i;
+
+      firewall_operate_load_rules(main);
+      if (F_status_is_error(main->setting.state.status) || (main->setting.flag & firewall_main_flag_operation_stop_e) || main->setting.state.status == F_child) return;
+    } // for
+
+    main->setting.state.status = F_okay;
+  }
+#endif // _di_firewall_operate_load_chains_
+
 #ifndef _di_firewall_operate_load_rules_
   void firewall_operate_load_rules(firewall_main_t * const main) {
 
-    if (!main) return;
+    if (!main || F_status_is_error_not(main->setting.state.status) && main->setting.state.status == F_child) return;
 
     main->data.buffer.used = 0;
     main->data.delimits.used = 0;
     main->data.rule_objects.used = 0;
     main->data.rule_contents.used = 0;
 
+// @fixme the data.rule_objects and rule_contents may be in use by a caller function (specifically in operate.c via firewall_operate_buffer_rules()).
     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)) {
@@ -30,6 +57,16 @@ extern "C" {
       return;
     }
 
+    firewall_operate_process_rules(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));
+      }
+
+      return;
+    }
+
     main->setting.state.status = F_okay;
   }
 #endif // _di_firewall_operate_load_rules_
index e4b363261cefa1d4271f3e776e4c94f92a974038..0a030ae4e7803dfdfd2709ddba7a80a7f62caf05 100644 (file)
@@ -17,21 +17,55 @@ extern "C" {
 #endif
 
 /**
- * Process buffered rules.
+ * Load and process the Content chains.
  *
- * @param data
- *   The program data.
- * @param chain
- *   The position representing the current chain being processed.
+ * @param main
+ *   The main program and setting data.
  *
- * @return
- *   F_okay on success.
- *   F_child on child process exiting.
+ *   This alters:
+ *     - main.data.is.
+ *     - main.data.range.
  *
- *   Status codes (with error bit) are returned on any problem.
+ *   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_load_rules()
+ *
+ * @see firewall_operate_load_rules()
+ */
+#ifndef _di_firewall_operate_load_chains_
+  extern void firewall_operate_load_chains(firewall_main_t * const main);
+#endif // _di_firewall_operate_load_chains_
+
+/**
+ * Load and process the rules.
+ *
+ * @param main
+ *   The main program and setting data.
+ *
+ *   This alters:
+ *     - main.data.buffer.
+ *     - main.data.delimits.
+ *     - main.data.rule_objects.
+ *     - main.data.rule_contents.
+ *
+ *   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_fss_apply_delimit()
+ *     Errors (with error bit) from: firewall_operate_process_rules()
+ *     Errors (with error bit) from: fll_fss_extended_read()
+ *
+ * @see f_fss_apply_delimit()
+ * @see firewall_operate_process_rules()
+ * @see fll_fss_extended_read()
  */
 #ifndef _di_firewall_operate_load_rules_
-  extern f_status_t firewall_operate_load_rules(firewall_main_t * const main);
+  extern void firewall_operate_load_rules(firewall_main_t * const main);
 #endif // _di_firewall_operate_load_rules_
 
 #ifdef __cplusplus
index d804c6ae80bdd5aa8545317029731916ef620c23..d0f5378d81aac76b0ad8643406b3999b4658b690 100644 (file)
 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) {
+  void firewall_operate_process_rules(firewall_main_t * const main) {
 
-    if (!main) return;
+    if (!main || F_status_is_error_not(main->setting.state.status) && main->setting.state.status == F_child) return;
 
-    bool invalid = F_false;
+    bool valid = F_true;
     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;
+    uint8_t chain = firewall_chain_none_e;
+    uint8_t direction = firewall_direction_none_e;
+    uint8_t action = firewall_action_append_e;
 
     int return_code = 0;
-
+    f_number_unsigned_t at = 0;
     f_number_unsigned_t i = 0;
-    f_number_unsigned_t r = 0;
+    f_number_unsigned_t j = 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;
+    f_string_static_t tool = firewall_tool_iptables_s;
+    f_ranges_t * const rule_objects = &data->main.rule_objects;
+    f_rangess_t * const rule_contents = data->main.rule_contents;
 
-        status = f_string_dynamic_append(data->devices.array[local->device], &device);
+    if (!(main->data.is & firewall_data_is_global_e)) {
+      if (data->devices.array[data->main.device].used) {
+        main->cache.device.used = 0;
 
-        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;
-        }
+        main->setting.state.status = f_string_dynamic_append(data->devices.array[data->main.device], &main->cache.device);
+        if (F_status_is_error(main->setting.state.status)) return;
       }
     }
 
     // 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;
+    if (!(main->data.is & firewall_data_is_stop_main_lock_e)) {
+      chain = firewall_chain_custom_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);
+    for (; i < rule_objects->used; ++i) {
 
-          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;
+      if (firewall_signal_check(main)) return;
 
+      valid = F_true;
       is_ip_list = F_false;
       ip_list_direction = F_false;
 
-      ip_list.used = 0;
+      main->cache.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) {
+      if (f_compare_dynamic_partial_string(firewall_chain_s.string, data->main.buffer, firewall_chain_s.used, rule_objects->array[i]) == F_equal_to) {
+        if (chain == firewall_chain_custom_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);
+          firewall_print_warning_chain_meaningless_line(&main->program.warning, i);
 
           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;
+        if (rule_contents->array[i].used != 1) {
+          valid = F_false;
         }
-        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_partial_string(firewall_chain_input_s.string, data->main.buffer, firewall_chain_input_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          chain = firewall_chain_input_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_partial_string(firewall_chain_output_s.string, data->main.buffer, firewall_chain_output_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          chain = firewall_chain_output_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_partial_string(firewall_chain_forward_s.string, data->main.buffer, firewall_chain_forward_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          chain = firewall_chain_forward_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_partial_string(firewall_chain_postrouting_s.string, data->main.buffer, firewall_chain_postrouting_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          chain = firewall_chain_postrouting_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_partial_string(firewall_chain_prerouting_s.string, data->main.buffer, firewall_chain_prerouting_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          chain = firewall_chain_prerouting_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 if (f_compare_dynamic_partial_string(firewall_chain_none_s.string, data->main.buffer, firewall_chain_none_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          chain = firewall_chain_none_e;
         }
         else {
-          invalid = F_true;
+          valid = F_false;
         }
 
-        if (!invalid) continue;
+        if (valid) 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_partial_string(firewall_direction_s.string, data->main.buffer, firewall_direction_s.used, rule_objects->array[i]) == F_equal_to) {
+        if (rule_contents->array[i].used != 1) {
+          valid = F_false;
         }
-        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_partial_string(firewall_direction_input_s.string, data->main.buffer, firewall_direction_input_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          direction = firewall_direction_input_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_partial_string(firewall_direction_output_s.string, data->main.buffer, firewall_direction_output_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          direction = firewall_direction_output_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 if (f_compare_dynamic_partial_string(firewall_direction_none_s.string, data->main.buffer, firewall_direction_none_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          direction = firewall_direction_none_e;
         }
         else {
 
           // Direction must be specified, and no custom directions are allowed.
-          invalid = F_true;
+          valid = F_false;
         }
 
-        if (!invalid) continue;
+        if (valid) 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_partial_string(firewall_device_s.string, data->main.buffer, firewall_device_s.used, rule_objects->array[i]) == F_equal_to) {
+        if (rule_contents->array[i].used != 1) {
+          valid = F_false;
         }
-        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);
+        else if (f_compare_dynamic_partial_string(firewall_device_all_s.string, data->main.buffer, firewall_device_all_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          main->cache.device.used = 0;
 
           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 if (f_compare_dynamic_partial_string(firewall_device_this_s.string, data->main.buffer, firewall_device_this_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          if (data->devices.array[data->main.device].used) {
+            main->setting.state.status = f_string_dynamic_append(data->devices.array[data->main.device], &main->cache.device);
           }
           else {
-            f_memory_array_resize(0, sizeof(f_char_t), (void **) &device.string, &device.used, &device.size);
+            main->cache.device.used = 0;
           }
 
+          if (F_status_is_error(main->setting.state.status)) return;
+
           continue;
         }
 
-        if (!invalid) {
-          device.used = 0;
+        if (valid) {
+          main->cache.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;
-          }
+          main->setting.state.status = f_string_dynamic_partial_append(data->main.buffer, rule_contents->array[i].array[0], &main->cache.device);
+          if (F_status_is_error(main->setting.state.status)) return;
 
           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_partial_string(firewall_action_s.string, data->main.buffer, firewall_action_s.used, rule_objects->array[i]) == F_equal_to) {
+        if (rule_contents->array[i].used != 1) {
+          valid = F_false;
         }
-        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_partial_string(firewall_action_append_s.string, data->main.buffer, firewall_action_append_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          action = firewall_action_append_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_partial_string(firewall_action_insert_s.string, data->main.buffer, firewall_action_insert_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          action = firewall_action_insert_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_partial_string(firewall_action_policy_s.string, data->main.buffer, firewall_action_policy_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          action = firewall_action_policy_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 if (f_compare_dynamic_partial_string(firewall_action_none_s.string, data->main.buffer, firewall_action_none_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+          action = firewall_action_none_e;
         }
         else {
-          invalid = F_true;
+          valid = F_false;
         }
 
-        if (!invalid) continue;
+        if (valid) 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;
+      else if (f_compare_dynamic_partial_string(firewall_ip_list.string, data->main.buffer, firewall_ip_list.used, rule_objects->array[i]) == F_equal_to) {
         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) {
+        if (f_compare_dynamic_partial_string(firewall_ip_list_source_s.string, data->main.buffer, firewall_ip_list_source_s.used, rule_contents->array[i].array[0]) == 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) {
+        else if (f_compare_dynamic_partial_string(firewall_ip_list_destination_s.string, data->main.buffer, firewall_ip_list_destination_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
           ip_list_direction = F_true;
         }
         else {
-          invalid = F_true;
+          valid = F_false;
         }
       }
-      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_partial_string(firewall_protocol_s.string, data->main.buffer, firewall_protocol_s.used, rule_objects->array[i]) == F_equal_to) {
+        if (rule_contents->array[i].used != 1) {
+          valid = F_false;
         }
         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) {
+          if (f_compare_dynamic_partial_string(firewall_protocol_none_s.string, data->main.buffer, firewall_protocol_none_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
             use_protocol = F_false;
           }
-          else if (length) {
-            protocol.used = 0;
+          else if (rule_contents->array[i].array[0].start <= rule_contents->array[i].array[0].stop) {
+            main->cache.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;
+            main->setting.state.status = f_string_dynamic_partial_append(data->main.buffer, rule_contents->array[i].array[0], &main->cache.protocol);
+            if (F_status_is_error(main->setting.state.status)) return;
 
             use_protocol = F_true;
           }
@@ -273,525 +208,384 @@ extern "C" {
       }
 
       // 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_partial_string(firewall_tool_s.string, data->main.buffer, firewall_tool_s.used, rule_objects->array[i]) == F_equal_to) {
+        if (rule_contents->array[i].used != 1) {
+          valid = F_false;
         }
         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;
+          if (f_compare_dynamic_partial_string(firewall_tool_iptables_s.string, data->main.buffer, firewall_tool_iptables_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+            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;
+          else if (f_compare_dynamic_partial_string(firewall_tool_ip6tables_s.string, data->main.buffer, firewall_tool_ip6tables_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+            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;
+          else if (f_compare_dynamic_partial_string(firewall_tool_ip46tables_s.string, data->main.buffer, firewall_tool_ip46tables_s.used, rule_contents->array[i].array[0]) == F_equal_to) {
+            tool = firewall_tool_iptables_s;
             repeat = 2;
           }
           else {
-            invalid = F_true;
+            valid = F_false;
           }
 
-          if (!invalid) continue;
+          if (valid) 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);
-        }
+      else if (f_compare_dynamic_partial_string(firewall_rule_s.string, data->main.buffer, firewall_rule_s.used, rule_objects->array[i]) == F_equal_to) {
+        firewall_print_warning_object_invalid_missing_line(&main->program.warning, i, main->data.buffer, main->data.rule_objects.array[i]);
 
         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);
-        }
+      if (!valid) {
+        firewall_print_warning_content_invalid_missing_line(&main->program.warning, i, main->data.buffer, main->data.rule_objects.array[i]);
 
         continue;
       }
 
-      for (r = repeat; F_status_is_error_not(status) && r; --r) {
+      for (j = repeat; F_status_is_error_not(main->setting.state.status) && j; --j) {
 
-        arguments.used = 0;
+        if (firewall_signal_check(main)) return;
 
         // 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;
+        main->cache.arguments.used = 0;
 
-        if (tool == firewall_program_ip46tables_e) {
-          if (r == 2) {
-            current_tool = firewall_tool_iptables_s;
-          }
-          else {
-            current_tool = firewall_tool_ip6tables_s;
-          }
+        main->setting.state.status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
+        if (F_status_is_error(main->setting.state.status)) return;
+
+        if (tool.string == firewall_tool_ip46tables_s.string) {
+          tool = (j == 2) ? firewall_tool_iptables_s : 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;
+        if (chain != firewall_chain_none_e && action != firewall_action_none_e) {
+          main->setting.state.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(main->setting.state.status)) return;
 
-          arguments.array[arguments.used].used = 0;
+          main->cache.arguments.array[main->cache.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]);
+          if (action == firewall_action_append_e) {
+            main->setting.state.status = f_string_dynamic_append(firewall_action_append_command_s, &main->cache.arguments.array[main->cache.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_insert_e) {
+            main->setting.state.status = f_string_dynamic_append(firewall_action_insert_command_s, &main->cache.arguments.array[main->cache.arguments.used]);
           }
-          else if (action == firewall_action_policy_id_e) {
-            status = f_string_dynamic_append(firewall_action_policy_command_s, &arguments.array[arguments.used]);
+          else if (action == firewall_action_policy_e) {
+            main->setting.state.status = f_string_dynamic_append(firewall_action_policy_command_s, &main->cache.arguments.array[main->cache.arguments.used]);
           }
 
-          if (F_status_is_error(status)) break;
+          if (F_status_is_error(main->setting.state.status)) return;
 
-          if (action == firewall_action_append_id_e || action == firewall_action_insert_id_e || action == firewall_action_policy_id_e) {
-            ++arguments.used;
+          if (action == firewall_action_append_e || action == firewall_action_insert_e || action == firewall_action_policy_e) {
+            ++main->cache.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;
+            main->setting.state.status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
+            if (F_status_is_error(main->setting.state.status)) return;
 
-            arguments.array[arguments.used].used = 0;
-            status = F_data_not;
+            main->cache.arguments.array[main->cache.arguments.used].used = 0;
+            main->setting.state.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]);
+            if (chain == firewall_chain_custom_e) {
+              main->setting.state.status = f_string_dynamic_append(data->chains.array[data->main.chain_ids.array[main->data.chain]], &main->cache.arguments.array[main->cache.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_forward_e) {
+              main->setting.state.status = f_string_dynamic_append(firewall_chain_forward_s, &main->cache.arguments.array[main->cache.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_postrouting_e) {
+              main->setting.state.status = f_string_dynamic_append(firewall_chain_postrouting_s, &main->cache.arguments.array[main->cache.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_prerouting_e) {
+              main->setting.state.status = f_string_dynamic_append(firewall_chain_prerouting_s, &main->cache.arguments.array[main->cache.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_input_e) {
+              main->setting.state.status = f_string_dynamic_append(firewall_chain_input_s, &main->cache.arguments.array[main->cache.arguments.used]);
             }
-            else if (chain == firewall_chain_output_id_e) {
-              status = f_string_dynamic_append(firewall_chain_output_s, &arguments.array[arguments.used]);
+            else if (chain == firewall_chain_output_e) {
+              main->setting.state.status = f_string_dynamic_append(firewall_chain_output_s, &main->cache.arguments.array[main->cache.arguments.used]);
             }
 
-            if (F_status_is_error(status)) break;
+            if (F_status_is_error(main->setting.state.status)) return;
 
-            if (status == F_data_not) {
-              status = F_okay;
+            if (main->setting.state.status == F_data_not) {
+              main->setting.state.status = F_okay;
             }
             else {
-              ++arguments.used;
+              ++main->cache.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 (device.used && (direction == firewall_direction_input_e || direction == firewall_direction_output_e)) {
+          if (f_compare_dynamic_partial_string(firewall_device_all_s.string, data->main.buffer, firewall_device_all_s.used, rule_contents->array[i].array[0]) == F_equal_to_not) {
+            main->setting.state.status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
+            if (F_status_is_error(main->setting.state.status)) return;
 
-            if (direction == firewall_direction_input_id_e) {
-              status = f_string_dynamic_append(firewall_device_input_command_s, &arguments.array[arguments.used]);
+            main->cache.arguments.array[main->cache.arguments.used].used = 0;
 
-              if (F_status_is_error(status)) break;
+            if (direction == firewall_direction_input_e) {
+              main->setting.state.status = f_string_dynamic_append(firewall_device_input_command_s, &main->cache.arguments.array[main->cache.arguments.used]);
+              if (F_status_is_error(main->setting.state.status)) return;
 
-              ++arguments.used;
+              ++main->cache.arguments.used;
             }
-            else if (direction == firewall_direction_output_id_e) {
-              status = f_string_dynamic_append(firewall_device_output_command_s, &arguments.array[arguments.used]);
+            else if (direction == firewall_direction_output_e) {
+              main->setting.state.status = f_string_dynamic_append(firewall_device_output_command_s, &main->cache.arguments.array[main->cache.arguments.used]);
+              if (F_status_is_error(main->setting.state.status)) return;
 
-              if (F_status_is_error(status)) break;
-
-              ++arguments.used;
+              ++main->cache.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;
+          if (main->cache.device.used) {
+            main->setting.state.status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
+            if (F_status_is_error(main->setting.state.status)) return;
 
-            status = f_string_dynamic_append(device, &arguments.array[arguments.used]);
+            main->cache.arguments.array[main->cache.arguments.used].used = 0;
 
-            if (F_status_is_error(status)) break;
+            main->setting.state.status = f_string_dynamic_append(main->cache.device, &main->cache.arguments.array[main->cache.arguments.used]);
+            if (F_status_is_error(main->setting.state.status)) return;
 
-            ++arguments.used;
+            ++main->cache.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]);
+          main->setting.state.status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
+          if (F_status_is_error(main->setting.state.status)) return;
 
-          if (F_status_is_error(status)) break;
+          main->cache.arguments.array[main->cache.arguments.used].used = 0;
 
-          ++arguments.used;
+          main->setting.state.status = f_string_dynamic_append(firewall_protocol_command_s, &main->cache.arguments.array[main->cache.arguments.used]);
+          if (F_status_is_error(main->setting.state.status)) return;
 
-          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;
+          ++main->cache.arguments.used;
 
-            arguments.array[arguments.used].used = 0;
+          if (main->cache.protocol.used) {
+            main->setting.state.status = f_memory_array_increase(firewall_default_allocation_step_d, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
+            if (F_status_is_error(main->setting.state.status)) return;
 
-            status = f_string_dynamic_append(protocol, &arguments.array[arguments.used]);
+            main->cache.arguments.array[main->cache.arguments.used].used = 0;
 
-            if (F_status_is_error(status)) break;
+            main->setting.state.status = f_string_dynamic_append(main->cache.protocol, &main->cache.arguments.array[main->cache.arguments.used]);
+            if (F_status_is_error(main->setting.state.status)) return;
 
-            ++arguments.used;
+            ++main->cache.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 && rule_contents->array[i].used > 0) || (is_ip_list && rule_contents->array[i].used > 1)) {
+          j = 0;
 
           if (is_ip_list) {
 
             // Skip past the chain.
-            ++subcounter;
+            ++j;
 
-            length = (local->rule_contents.array[i].array[subcounter].stop - local->rule_contents.array[i].array[subcounter].start) + 1;
-
-            if (length) {
+            if (rule_contents->array[i].array[j].start <= rule_contents->array[i].array[j].stop) {
               ip_list.used = 0;
 
-              status = f_string_dynamic_partial_append(local->buffer, local->rule_contents.array[i].array[subcounter], &ip_list);
+              main->setting.state.status = f_string_dynamic_partial_append(data->main.buffer, rule_contents->array[i].array[j], &ip_list);
 
-              if (F_status_is_error(status)) {
+              if (F_status_is_error(main->setting.state.status)) {
 
                 // Prevent the loop below from being processed.
-                subcounter = local->rule_contents.array[i].used;
+                j = rule_contents->array[i].used;
               }
               else {
-                ++subcounter;
+                ++j;
               }
             }
           }
 
-          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;
+          main->setting.state.status = f_memory_array_increase_by(rule_contents->array[i].used, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
+          if (F_status_is_error(main->setting.state.status)) return;
 
-          for (; subcounter < local->rule_contents.array[i].used; ++subcounter) {
+          for (; j < rule_contents->array[i].used; ++j) {
 
-            length = (local->rule_contents.array[i].array[subcounter].stop - local->rule_contents.array[i].array[subcounter].start) + 1;
+            if (firewall_signal_check(main)) return;
 
-            if (length) {
-              arguments.array[arguments.used].used = 0;
+            if (rule_contents->array[i].array[j].start <= rule_contents->array[i].array[j].stop) {
+              main->cache.arguments.array[main->cache.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;
+              main->setting.state.status = f_string_dynamic_partial_append(data->main.buffer, rule_contents->array[i].array[j], &main->cache.arguments.array[main->cache.arguments.used]);
+              if (F_status_is_error(main->setting.state.status)) return;
 
-              ++arguments.used;
+              ++main->cache.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);
+          firewall_print_warning_content_invalid_missing_line(&main->program.warning, i, main->data.buffer, main->data.rule_objects.array[i]);
 
           break;
         }
 
         // Now execute the generated commands.
-        if (arguments.used > 1) {
+        if (main->cache.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;
+            data->cache.path_file_specific.used = 0;
+            data->cache.local_buffer.used = 0;
+            data->cache.basic_objects.used = 0;
+            data->cache.basic_contents.used = 0;
 
-            status = f_string_dynamic_append(firewall_network_path_s, &path_file);
+            main->setting.state.status = f_string_dynamic_append(firewall_network_path_s, &data->cache.path_file_specific);
 
-            if (F_status_is_error_not(status)) {
-              status = f_string_dynamic_append(ip_list, &path_file);
+            if (F_status_is_error_not(main->setting.state.status)) {
+              main->setting.state.status = f_string_dynamic_append(main->cache.ip_list, &data->cache.path_file_specific);
             }
 
-            if (F_status_is_error_not(status)) {
-              status = f_file_open(path_file, 0, &file);
+            if (F_status_is_error(main->setting.state.status)) {
+              firewall_print_error(&main->program.error, macro_firewall_f(f_string_dynamic_append));
+
+              return;
             }
 
-            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) {
+            main->setting.state.status = f_file_open(data->cache.path_file_specific, 0, &data->cache.file);
 
-                // 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);
-                }
+            if (F_status_is_error(main->setting.state.status)) {
+              firewall_print_error_file(&main->program.error, macro_firewall_f(f_file_open), data->cache.path_file_specific, f_file_operation_open_s, fll_error_file_type_file_e);
 
-                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_close(&data->cache.file);
 
-              f_file_stream_flush(file);
-              f_file_stream_close(&file);
+              return;
             }
-            else {
-              status = f_file_read(file, &local_buffer);
 
-              f_file_stream_flush(file);
-              f_file_stream_close(&file);
+            main->setting.state.status = f_file_read(data->cache.file, &data->cache.local_buffer);
 
-              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_file_stream_close(&data->cache.file);
 
-                {
-                  f_state_t state = f_state_t_initialize;
-                  f_range_t input = macro_f_range_t_initialize_2(local_buffer.used);
+            if (F_status_is_error(main->setting.state.status)) {
+              firewall_print_error_file(&main->program.error, macro_firewall_f(f_file_read), data->cache.path_file_specific, f_file_operation_read_s, fll_error_file_type_file_e);
 
-                  status = fll_fss_basic_read(local_buffer, state, &input, &basic_objects, &basic_contents, 0, &delimits, 0);
-                }
+              return;
+            }
 
-                if (F_status_set_error(status)) {
-                  status = F_status_set_fine(status);
+            main->data.delimits.used = 0;
+            main->data.range.start = 0;
+            main->data.range.stop = data->cache.local_buffer.used - 1;
 
-                  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);
-                  }
+            main->setting.state.status = fll_fss_basic_read(data->cache.local_buffer, main->setting.state.status, &input, &data->cache.basic_objects, &data->cache.basic_contents, 0, &main->data.delimits, 0);
 
-                  status = F_status_set_error(status);
-                }
+            if (F_status_is_error(main->setting.state.status)) {
+              if (F_status_set_fine(main->setting.state.status) == F_data_not_eos || F_status_set_fine(main->setting.state.status) == F_data_not || F_status_set_fine(main->setting.state.status) == F_data_not_stop) {
+                // Empty files are to be silently ignored.
+              }
+              else {
+                firewall_print_error_file(&main->program.error, macro_firewall_f(fll_fss_basic_read), data->cache.path_file_specific, f_file_operation_read_s, fll_error_file_type_file_e);
 
-                if (F_status_is_error_not(status)) {
-                  f_state_t state = f_state_t_initialize;
+                return;
+              }
+            }
 
-                  status = f_fss_apply_delimit(state, delimits, &local_buffer);
+            main->setting.state.status = f_fss_apply_delimit(main->setting.state, main->data.delimits, &data->cache.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(main->setting.state.status)) {
+              firewall_print_error(&main->program.error, macro_firewall_f(f_fss_apply_delimit));
+            }
 
-                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(main->setting.state.status)) {
+              main->setting.state.status = f_memory_array_increase_by(2, sizeof(f_string_dynamic_t), (void **) &main->cache.arguments.array, &main->cache.arguments.used, &main->cache.arguments.size);
 
-                  if (F_status_is_error_not(status)) {
-                    arguments.array[arguments.used].used = 0;
+              if (F_status_is_error(main->setting.state.status)) {
+                firewall_print_error(&main->program.error, macro_firewall_f(f_memory_array_increase_by));
 
-                    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);
+                return;
+              }
 
-                    break;
-                  }
+              main->cache.arguments.array[main->cache.arguments.used].used = 0;
 
-                  ++arguments.used;
+              main->setting.state.status = f_string_dynamic_append(ip_list_direction ? firewall_ip_list_destination_action_s : firewall_ip_list_source_action_s, &main->cache.arguments.array[main->cache.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) {
+              if (F_status_is_error(main->setting.state.status)) {
+                firewall_print_error(&main->program.error, macro_firewall_f(f_string_dynamic_append));
 
-                    arguments.array[arguments.used].used = 0;
+                return;
+              }
 
-                    status = f_string_dynamic_partial_append(local_buffer, basic_objects.array[at], &arguments.array[arguments.used]);
-                    if (F_status_is_error(status)) break;
+              ++main->cache.arguments.used;
 
-                    ++arguments.used;
+              // The ip_list file contains objects and no content, all objects are what matter an nothing else.
+              for (at = 0; at < data->cache.basic_objects.used; ++at) {
 
-                    firewall_print_debug_tool(data->main->warning, current_tool, arguments);
+                if (firewall_signal_check(main)) return;
 
-                    status = fll_execute_program(current_tool, arguments, 0, 0, (void *) &return_code);
+                main->cache.arguments.array[main->cache.arguments.used].used = 0;
 
-                    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);
+                main->setting.state.status = f_string_dynamic_partial_append(data->cache.local_buffer, data->cache.basic_objects.array[at], &main->cache.arguments.array[main->cache.arguments.used]);
 
-                      f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+                if (F_status_is_error(main->setting.state.status)) {
+                  firewall_print_error(&main->program.error, macro_firewall_f(f_string_dynamic_partial_append));
 
-                      data->main->child = return_code;
+                  return;
+                }
 
-                      return status;
-                    }
+                ++main->cache.arguments.used;
 
-                    // Remove ip_argument from arguments string.
-                    --arguments.used;
+                firewall_print_debug_tool(data->main->warning, tool, main->cache.arguments);
 
-                    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));
-                      }
+                main->setting.state.status = fll_execute_program(tool, main->cache.arguments, 0, 0, (void *) &return_code);
 
-                      break;
-                    }
-                  } // for
+                if (main->setting.state.status == F_child) {
+                  data->main->child = return_code;
 
-                  // Remove ip_list_action from arguments string.
-                  --arguments.used;
+                  return;
                 }
 
-                f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &delimits.array, &delimits.used, &delimits.size);
-              }
-            }
+                // Remove ip_argument from arguments string.
+                --main->cache.arguments.used;
 
-            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);
+                if (F_status_is_error(main->setting.state.status)) {
+                  if (F_status_set_fine(main->setting.state.status) == F_failure) {
+                    firewall_print_error_operation(main->program->error, tool, main->cache.arguments);
+                  }
+                  else {
+                    firewall_print_error(&main->program.error, macro_firewall_f(fll_execute_program));
+                  }
 
-            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);
+                  return;
+                }
+              } // for
 
-            if (F_status_set_fine(status) == F_failure || F_status_set_fine(status) == F_parameter) break;
+              // Remove ip_list_action from arguments string.
+              --main->cache.arguments.used;
+            }
+
+            if (F_status_set_fine(main->setting.state.status) == F_failure || F_status_set_fine(main->setting.state.status) == F_parameter) return;
           }
           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);
+            firewall_print_debug_tool(data->main->warning, tool, main->cache.arguments);
 
-              f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &arguments.string, &arguments.used, &arguments.size, &f_string_dynamics_delete_callback);
+            main->setting.state.status = fll_execute_program(tool, main->cache.arguments, 0, 0, (void *) &return_code);
 
+            if (main->setting.state.status == F_child) {
               data->main->child = return_code;
 
-              return status;
+              return;
             }
 
-            if (F_status_is_error(status)) {
-              if (F_status_set_fine(status) == F_failure) {
-                firewall_print_error_operation(data->main->error, current_tool, arguments);
+            if (F_status_is_error(main->setting.state.status)) {
+              if (F_status_set_fine(main->setting.state.status) == F_failure) {
+                firewall_print_error_operation(main->program->error, tool, main->cache.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));
+              else {
+                firewall_print_error(&main->program.error, macro_firewall_f(fll_execute_program));
               }
 
-              break;
+              return;
             }
           }
         }
       } // 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;
+    main->setting.state.status = F_okay;
   }
 #endif // _di_firewall_operate_process_rules_perform_
 
index d3a612a090adfa56aa114bb29d87bfe411f6c49b..e4a18bbdcfb4ec28dccb31e09bea660429f9abb2 100644 (file)
@@ -17,25 +17,6 @@ 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
@@ -50,9 +31,9 @@ extern "C" {
  *
  * @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_
+#ifndef _di_firewall_operate_process_rules_
+  extern void firewall_operate_process_rules(firewall_main_t * const main);
+#endif // _di_firewall_operate_process_rules_
 
 #ifdef __cplusplus
 } // extern "C"
diff --git a/level_3/firewall/c/main/print/data.c b/level_3/firewall/c/main/print/data.c
deleted file mode 100644 (file)
index 9bcd373..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "../firewall.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/level_3/firewall/c/main/print/data.h b/level_3/firewall/c/main/print/data.h
deleted file mode 100644 (file)
index 7b1da58..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * 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
index 2ce2b5e30e2d4e641a3475dc778c7f05b9dfc16b..edea597aca462b7ca03133dc011f2a79d679a010 100644 (file)
@@ -30,69 +30,38 @@ extern "C" {
   }
 #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) {
+#ifndef _di_firewall_print_error_file_empty_
+  f_status_t firewall_print_error_file_empty(fl_print_t * const print, const f_string_static_t section, const f_string_static_t file) {
 
     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_
+    f_file_stream_lock(print->to);
 
-#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) {
+    fl_print_format("%[%QNo relevant data is found within the file '%]", 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(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
 
-    if (output.verbosity == f_console_verbosity_quiet_e) return;
+    f_file_stream_unlock(print->to);
 
-    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);
+    return F_okay;
   }
-#endif // _di_firewall_print_error_on_invalid_parameter_
+#endif // _di_firewall_print_error_file_empty_
 
-#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) {
+#ifndef _di_firewall_print_error_network_device_none_
+  f_status_t firewall_print_error_network_device_none(fl_print_t * const print) {
 
-    if (!print || !print->custom) return F_status_set_error(F_output_not);
+    if (!print) 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);
+    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_unhandled_
+#endif // _di_firewall_print_error_network_device_none_
 
 #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) {
+  f_status_t firewall_print_error_operation(fl_print_t * const print, 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;
@@ -127,7 +96,7 @@ extern "C" {
 #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) {
+  f_status_t firewall_print_error_operation_files_missing(fl_print_t * const 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;
@@ -138,9 +107,9 @@ extern "C" {
 
     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(" %[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(" %[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);
 
@@ -168,10 +137,6 @@ extern "C" {
     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);
@@ -187,6 +152,36 @@ extern "C" {
   }
 #endif // _di_firewall_print_error_directory_read_
 
+#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_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 58334fa2594d23f36be0f3d644cd83ce2e431385..0316e019f645283cd6ee14d4e6711accd7c99255 100644 (file)
@@ -68,12 +68,16 @@ extern "C" {
 #endif // _di_firewall_print_error_file_
 
 /**
- * Print error message regarding being unable to find any devices.
+ * Print file related error message regarding that there is no relevant data in the file.
+ *
+ * The file is effectively empty but could have comments or other non-valid (aka non-Object) data.
  *
  * @param print
  *   The output structure to print to.
  *
  *   This does not alter print.custom.setting.state.status.
+ * @param file
+ *   The name of the file.
  *
  * @return
  *   F_okay on success.
@@ -81,46 +85,31 @@ extern "C" {
  *
  *   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.
+ * @see fll_error_file_print()
  */
-#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_
+#ifndef _di_firewall_print_error_file_empty_
+  extern f_status_t firewall_print_error_file_empty(fl_print_t * const print, const f_string_static_t file);
+#endif // _di_firewall_print_error_file_empty_
 
 /**
- * Print an unhandled error for the given function.
+ * 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.
- * @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.
+ *
+ * @see fll_error_print()
  */
-#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_
+#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 error about the given operation failed.
@@ -141,7 +130,7 @@ extern "C" {
  *   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);
+  extern f_status_t firewall_print_error_operation(fl_print_t * const print, const f_string_static_t tool, const f_string_statics_t arguments);
 #endif // _di_firewall_print_error_operation_
 
 /**
@@ -164,7 +153,7 @@ extern "C" {
  *   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);
+  extern f_status_t firewall_print_error_operation_files_missing(fl_print_t * const print, const f_string_static_t operation, const f_string_static_t file);
 #endif // _di_firewall_print_error_operation_files_missing_
 
 /**
@@ -187,6 +176,29 @@ extern "C" {
   extern f_status_t firewall_print_error_operation_specified_not(fl_print_t * const print);
 #endif // _di_firewall_print_error_operation_specified_not_
 
+/**
+ * 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_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/level_3/firewall/c/main/print/verbose.c b/level_3/firewall/c/main/print/verbose.c
deleted file mode 100644 (file)
index 9bcd373..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "../firewall.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/level_3/firewall/c/main/print/verbose.h b/level_3/firewall/c/main/print/verbose.h
deleted file mode 100644 (file)
index f00cf0c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * 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
index 428cbce9659a11c4f1c328c894205b3c0a8cc102..fae2355a87d868020b869614e149f43998c6fd68 100644 (file)
@@ -4,6 +4,79 @@
 extern "C" {
 #endif
 
+#ifndef _di_firewall_print_warning_chain_meaningless_line_
+  f_status_t firewall_print_warning_chain_meaningless_line(fl_print_t * const print, const f_number_unsigned_t line) {
+
+    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("%[%QAt line%] ", print->to, print->context, print->prefix, print->context);
+    fl_print_format(f_string_format_un_single_s.string, print->to, print->notable, line, print->notable);
+    fl_print_format("%[ the chain option is meaningless inside of a custom chain%]%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_chain_meaningless_line_
+
+#ifndef _di_firewall_print_warning_content_invalid_missing_line_
+  f_status_t firewall_print_warning_content_invalid_missing_line(fl_print_t * const print, const f_number_unsigned_t line, const f_string_static_t buffer, const f_range_t range) {
+
+    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("%[%QAt line%] ", print->to, print->context, print->prefix, print->context);
+    fl_print_format(f_string_format_un_single_s.string, print->to, print->notable, line, print->notable);
+    fl_print_format(" %[the object '%]", print->to, print->context, print->prefix, print->context);
+    fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->notable, buffer, range, print->notable);
+
+    if (range.start > range.stop) {
+      fl_print_format("%[' has no content.%]%r", print->to, print->context, print->context, f_string_eol_s);
+    }
+    else {
+      fl_print_format("%[' is invalid.%]%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_content_invalid_missing_line_
+
+#ifndef _di_firewall_print_warning_object_invalid_missing_line_
+  f_status_t firewall_print_warning_object_invalid_missing_line(fl_print_t * const print, const f_number_unsigned_t line, const f_string_static_t buffer, const f_range_t range) {
+
+    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("%[%QAt line%] ", print->to, print->context, print->prefix, print->context);
+    fl_print_format(f_string_format_un_single_s.string, print->to, print->notable, line, print->notable);
+
+    if (range.start > range.stop) {
+      fl_print_format(" %[the object is missing.%]%r", print->to, print->context, print->context, f_string_eol_s);
+    }
+    else {
+      fl_print_format(" %[the object '%]", print->to, print->context, print->prefix, print->context);
+      fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->notable, buffer, range, print->notable);
+      fl_print_format("%[' has no content.%]%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_object_invalid_missing_line_
+
 #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) {
 
index 0d1c509a2e90a42cd20618221c2d5b3b1dac460a..318e89b7a570191a6278525f012d7c87d1fcdfc1 100644 (file)
@@ -17,6 +17,74 @@ extern "C" {
 #endif
 
 /**
+ * Print warning message regarding chain being meaningless at the given line.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param line
+ *   The line number.
+ *
+ * @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_warning_chain_meaningless_line_
+  extern f_status_t firewall_print_warning_chain_meaningless_line(fl_print_t * const print, const f_number_unsigned_t line);
+#endif // _di_firewall_print_warning_chain_meaningless_line_
+
+/**
+ * Print warning message regarding a line having no Content or invalid Content for the given Object.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param line
+ *   The line number.
+ * @param buffer
+ *   The buffer containing the Object.
+ * @param range
+ *   The range within the buffer representing the Object.
+ *
+ * @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_warning_content_invalid_missing_line_
+  extern f_status_t firewall_print_warning_content_invalid_missing_line(fl_print_t * const print, const f_number_unsigned_t line, const f_string_static_t buffer, const f_range_t range);
+#endif // _di_firewall_print_warning_content_invalid_missing_line_
+
+/**
+ * Print warning message regarding a line having no Object or the Object is invalid.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param line
+ *   The line number.
+ * @param buffer
+ *   The buffer containing the Object.
+ * @param range
+ *   The range within the buffer representing the Object.
+ *
+ * @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_warning_object_invalid_missing_line_
+  extern f_status_t firewall_print_warning_object_invalid_missing_line(fl_print_t * const print, const f_number_unsigned_t line, const f_string_static_t buffer, const f_range_t range);
+#endif // _di_firewall_print_warning_object_invalid_missing_line_
+
+/**
  * Print warning message regarding a show option not being known.
  *
  * @param print
@@ -31,8 +99,6 @@ extern "C" {
  *   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);
index 300008fb8eab03a03e88546088aad053055489b4..781b40682f94871fd5bfed229c4a11c16ca02c8f 100644 (file)
@@ -36,11 +36,17 @@ build_libraries-individual_thread -lf_thread
 build_libraries-level -lfll_2 -lfll_1 -lfll_0
 build_libraries-monolithic -lfll
 
-build_sources_library firewall.c common.c print.c private-common.c private-firewall.c
+build_sources_library main/common.c main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c
+build_sources_library main/print/debug.c main/print/error.c main/print/message.c main/print/warning.c
+build_sources_library main/operate.c main/operate/buffer.c main/operate/create.c main/operate/default.c main/operate/delete.c main/operate/load.c main/operate/process.c
+build_sources_library main/firewall.c main/signal.c main/thread.c
 
-build_sources_program main.c
+build_sources_program main/main.c
 
-build_sources_headers firewall.h common.h print.h
+build_sources_headers main/common.h main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h
+build_sources_headers main/print/debug.h main/print/error.h main/print/message.h main/print/warning.h
+build_sources_headers main/operate.h main/operate/buffer.h main/operate/create.h main/operate/default.h main/operate/delete.h main/operate/load.h main/operate/process.h
+build_sources_headers main/firewall.h main/operate.h main/signal.h main/thread.h
 
 build_sources_documentation man