]> Kevux Git Server - kevux-tools/commitdiff
Update: Impove IP address processing code and logic.
authorKevin Day <Kevin@kevux.org>
Wed, 28 Jan 2026 05:54:03 +0000 (23:54 -0600)
committerKevin Day <Kevin@kevux.org>
Wed, 28 Jan 2026 06:01:00 +0000 (00:01 -0600)
The TacocaT program exposed problems in the `f_network_is_ip_address()` function (which is now fixed upstream).

Remove the code that affectively works around the problem.
Replace it with a cleaner implementation.

This implementation explicitly handles extracting the IPv4 or IPv6 addresses (and port numbers) through dedicated functions.
Pass these to the `f_network_to_ip_string()` as appropriate.

sources/c/program/kevux/tools/tacocat/main/common.c
sources/c/program/kevux/tools/tacocat/main/common.h

index b38d4f94870d7991b03fa476d87359f9fc204468..abb44e18dc35afc28080aa974039215315782592 100644 (file)
@@ -231,6 +231,80 @@ extern "C" {
   }
 #endif // _di_kt_tacocat_setting_load_
 
+#ifndef _di_kt_tacocat_setting_load_address_extract_
+  void kt_tacocat_setting_load_address_extract(kt_tacocat_main_t * const main, const uint8_t type, const f_range_double_t range_ip, const f_string_static_t address, f_string_dynamic_t * const extracted) {
+
+    if (!main) return;
+
+    if (!extracted) {
+      main->setting.state.status = F_status_set_error(F_parameter);
+
+      return;
+    }
+
+    if (!address.used) {
+      main->setting.state.status = F_data_not;
+
+      return;
+    }
+
+    extracted->used = 0;
+
+    if (type == f_network_family_ip_4_e || type == f_network_family_ip_6_e) {
+      const f_range_t range = macro_f_range_t_initialize_1(range_ip.start_1, range_ip.stop_1);
+
+      main->setting.state.status = f_string_dynamic_partial_append_nulless(address, range, extracted);
+    }
+    else {
+      main->setting.state.status = f_string_dynamic_append_nulless(address, extracted);
+    }
+
+    if (F_status_is_error_not(main->setting.state.status)) {
+      main->setting.state.status = f_string_dynamic_terminate_after(extracted);
+    }
+
+    if (F_status_is_error_not(main->setting.state.status)) {
+      main->setting.state.status = F_okay;
+    }
+  }
+#endif // _di_kt_tacocat_setting_load_address_extract_
+
+#ifndef _di_kt_tacocat_setting_load_address_port_extract_
+  void kt_tacocat_setting_load_address_port_extract(kt_tacocat_main_t * const main, const uint8_t type, const f_range_double_t range_ip, const f_string_static_t address, f_number_unsigned_t * const port) {
+
+    if (!main) return;
+
+    if (!port) {
+      main->setting.state.status = F_status_set_error(F_parameter);
+
+      return;
+    }
+
+    if (!address.used) {
+      main->setting.state.status = F_data_not;
+
+      return;
+    }
+
+    if (type != f_network_family_ip_4_e && type != f_network_family_ip_6_e) {
+      main->setting.state.status = F_number_not;
+
+      return;
+    }
+
+    if (range_ip.start_2 <= range_ip.stop_2) {
+      const f_string_static_t adjusted = macro_f_string_static_t_initialize_3(address.string + range_ip.start_2, (range_ip.stop_2 - range_ip.start_2) + 1);
+
+      *port = 0;
+
+      main->setting.state.status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, adjusted, port);
+      if (F_status_is_error(main->setting.state.status)) return;
+    }
+
+    main->setting.state.status = F_okay;
+  }
+#endif // _di_kt_tacocat_setting_load_address_port_extract_
+
 #ifndef _di_kt_tacocat_setting_load_send_receive_
   void kt_tacocat_setting_load_send_receive(const f_console_arguments_t arguments, kt_tacocat_main_t * const main) {
 
@@ -415,7 +489,7 @@ extern "C" {
                 sets[i]->array[j].socket.form = f_socket_address_form_generic_e;
               }
 
-              kt_tacocat_setting_load_address_port_extract(main, range_ip, &address, &sets[i]->array[j].port);
+              kt_tacocat_setting_load_address_port_extract(main, family.type, range_ip, address, &sets[i]->array[j].port);
 
               if (F_status_is_error(main->setting.state.status)) {
                 if (F_status_set_fine(main->setting.state.status) == F_parameter) {
@@ -442,11 +516,11 @@ extern "C" {
               }
 
               if (host.h_addrtype) {
-                main->setting.state.status = f_string_dynamic_append(address, &sets[i]->array[j].network);
+                kt_tacocat_setting_load_address_extract(main, family.type, range_ip, address, &sets[i]->array[j].network);
 
                 macro_kt_tacocat_handle_load_send_receive_error_continue_2();
 
-                main->setting.state.status = f_network_from_ip_string(address, &family);
+                main->setting.state.status = f_network_from_ip_string(sets[i]->array[j].network, &family);
 
                 macro_kt_tacocat_handle_load_send_receive_error_continue_2();
               }
@@ -615,54 +689,6 @@ extern "C" {
   }
 #endif // _di_kt_tacocat_setting_load_send_receive_
 
-#ifndef _di_kt_tacocat_setting_load_address_port_extract_
-  void kt_tacocat_setting_load_address_port_extract(kt_tacocat_main_t * const main, const f_range_double_t range_ip, f_string_static_t * const address, f_number_unsigned_t * const port) {
-
-    if (!main) return;
-
-    if (!address || !port) {
-      main->setting.state.status = F_status_set_error(F_parameter);
-
-      return;
-    }
-
-    if (!address->used) {
-      main->setting.state.status = F_data_not;
-
-      return;
-    }
-
-    if (main->setting.state.status == F_network_version_four || main->setting.state.status == F_network_version_six) {
-      if (range_ip.start_2 <= range_ip.stop_2) {
-        *port = 0;
-
-        {
-          char adjusted_string[(range_ip.stop_2 - range_ip.start_2) + 1];
-          const f_string_static_t adjusted = macro_f_string_static_t_initialize_3(adjusted_string, (range_ip.stop_2 - range_ip.start_2) + 1);
-          memcpy(adjusted_string, address->string + range_ip.start_2, adjusted.used);
-
-          main->setting.state.status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, adjusted, port);
-          if (F_status_is_error(main->setting.state.status)) return;
-        }
-
-        address->string[range_ip.start_2] = 0;
-        address->used = range_ip.start_2;
-
-        while (address->used && address->string[address->used] != f_string_ascii_colon_s.string[0]) --address->used;
-
-        // Be sure to also remove the colon.
-        address->string[address->used] = 0;
-      }
-
-      main->setting.state.status = F_okay;
-
-      return;
-    }
-
-    main->setting.state.status = F_number_not;
-  }
-#endif // _di_kt_tacocat_setting_load_address_port_extract_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 6b1732cf27cb8a871de91f4ab74a3a18afa8e551..1487fea3c5713646d89c4061234c5ff3877fcbd4 100644 (file)
@@ -54,16 +54,10 @@ extern "C" {
 #endif // _di_kt_tacocat_setting_load_
 
 /**
- * Perform the standard program setting load process for the send and receive parameters.
- *
- * This will perform any DNS resolutions as necessary and open any appropriate files.
- *
- * This prints error messages as appropriate.
+ * Process the string and extract the address.
  *
- * If either main or setting is NULL, then this immediately returns without doing anything.
+ * This does not print error messages.
  *
- * @param arguments
- *   The parameters passed to the process (often referred to as command line arguments).
  * @param main
  *   The main program and settings data.
  *
@@ -71,26 +65,35 @@ extern "C" {
  *
  *   This alters main.setting.state.status:
  *     F_okay on success.
+ *     F_data_not on success but there is nothing in the address string (address.used is 0).
  *
  *     F_parameter (with error bit) if a parameter is invalid.
  *
- *     Errors (with error bit) from: f_file_exists().
- *     Errors (with error bit) from: f_file_open().
- *     Errors (with error bit) from: f_memory_array_increase_by().
- *     Errors (with error bit) from: f_network_from_ip_name().
  *     Errors (with error bit) from: f_string_dynamic_append_nulless().
+ *     Errors (with error bit) from: f_string_dynamic_partial_append_nulless().
+ *     Errors (with error bit) from: f_string_dynamic_terminate_after().
+ * @param type
+ *   The network address type from f_network_family_ip_t.type.
+ * @param range_ip
+ *   The range in the string representing the extracted address and port number.
+ * @param address
+ *   The string representing the address to extract as a NULL terminated string.
+ * @param port
+ *   The extracted address.
  *
- *     Errors (with error bit) from: main.call.setting_load_send_receive().
+ *   When main.setting.state.status is set to either F_network_version_four or F_network_version_six when calling this function, the port represents the location within the address string that the port number begins.
+ *
+ *   Otherwise, this is a direct copy of the address.
+ *
+ *   Must not be NULL.
  *
- * @see f_file_exists()
- * @see f_file_open()
- * @see f_memory_array_increase_by()
- * @see f_network_from_ip_name()
  * @see f_string_dynamic_append_nulless()
+ * @see f_string_dynamic_partial_append_nulless()
+ * @see f_string_dynamic_terminate_after()
  */
-#ifndef _di_kt_tacocat_setting_load_send_receive_
-  extern void kt_tacocat_setting_load_send_receive(const f_console_arguments_t arguments, kt_tacocat_main_t * const main);
-#endif // _di_kt_tacocat_setting_load_send_receive_
+#ifndef _di_kt_tacocat_setting_load_address_extract_
+  extern void kt_tacocat_setting_load_address_extract(kt_tacocat_main_t * const main, const uint8_t type, const f_range_double_t range_ip, const f_string_static_t address, f_string_dynamic_t * const extracted);
+#endif // _di_kt_tacocat_setting_load_address_extract_
 
 /**
  * Process the string and extract any potential port numbers.
@@ -102,8 +105,6 @@ extern "C" {
  * @param main
  *   The main program and settings data.
  *
- *   The main.setting.state.status can be set to either F_network_version_four or F_network_version_six when calling this function to bypass IP type detection.
- *
  *   Must not be NULL.
  *
  *   This alters main.setting.state.status:
@@ -114,6 +115,8 @@ extern "C" {
  *     F_parameter (with error bit) if a parameter is invalid.
  *
  *     Errors (with error bit) from: fl_conversion_dynamic_to_unsigned_detect().
+ * @param type
+ *   The network address type from f_network_family_ip_t.type.
  * @param range_ip
  *   The range in the string representing the extracted address and port number.
  * @param address
@@ -128,8 +131,6 @@ extern "C" {
  *   - Octals (base 8) begin with either '0o' or '0O'.
  *   - Binaries (base 2) begin with either '0b' or '0B'.
  *   - Decimal (base 10) is used for all other cases.
- *
- *   Must not be NULL.
  * @param port
  *   The extracted port number.
  *
@@ -140,9 +141,48 @@ extern "C" {
  * @see fl_conversion_dynamic_to_unsigned_detect()
  */
 #ifndef _di_kt_tacocat_setting_load_address_port_extract_
-  extern void kt_tacocat_setting_load_address_port_extract(kt_tacocat_main_t * const main, const f_range_double_t range_ip, f_string_static_t * const address, f_number_unsigned_t * const port);
+  extern void kt_tacocat_setting_load_address_port_extract(kt_tacocat_main_t * const main, const uint8_t type, const f_range_double_t range_ip, const f_string_static_t address, f_number_unsigned_t * const port);
 #endif // _di_kt_tacocat_setting_load_address_port_extract_
 
+/**
+ * Perform the standard program setting load process for the send and receive parameters.
+ *
+ * This will perform any DNS resolutions as necessary and open any appropriate files.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately returns without doing anything.
+ *
+ * @param arguments
+ *   The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ *   The main program and settings data.
+ *
+ *   Must not be NULL.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *
+ *     F_parameter (with error bit) if a parameter is invalid.
+ *
+ *     Errors (with error bit) from: f_file_exists().
+ *     Errors (with error bit) from: f_file_open().
+ *     Errors (with error bit) from: f_memory_array_increase_by().
+ *     Errors (with error bit) from: f_network_from_ip_name().
+ *     Errors (with error bit) from: f_string_dynamic_append_nulless().
+ *
+ *     Errors (with error bit) from: main.call.setting_load_send_receive().
+ *
+ * @see f_file_exists()
+ * @see f_file_open()
+ * @see f_memory_array_increase_by()
+ * @see f_network_from_ip_name()
+ * @see f_string_dynamic_append_nulless()
+ */
+#ifndef _di_kt_tacocat_setting_load_send_receive_
+  extern void kt_tacocat_setting_load_send_receive(const f_console_arguments_t arguments, kt_tacocat_main_t * const main);
+#endif // _di_kt_tacocat_setting_load_send_receive_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif