]> Kevux Git Server - kevux-tools/commitdiff
Progress: Further work in TacocaT, getting the "receive" working and writing to a...
authorKevin Day <thekevinday@gmail.com>
Tue, 5 Sep 2023 02:25:56 +0000 (21:25 -0500)
committerKevin Day <thekevinday@gmail.com>
Tue, 5 Sep 2023 02:25:56 +0000 (21:25 -0500)
This gets the receive mostly working.
There may be a few fixme or todo comments to address.
I decided to not bother with some of the more complex handling of problems to get this program out the door.

To test this, I used the FLL-0.6 branch version of the file specifications/fss-000f.txt.
I then created the Packet header using the bash script like this:
  printf '\x00\x00\x00\x15\x78' > test.binary
  cat 0.6/specifications/fss-000f.txt >> test.binary

The resulting binary file size is 0x1578 bytes (5496 bytes) and this can be confirmed via the wc command:
  wc test.binary

I can then start the TacocaT program in a new terminal like this:
  tacocat -r 127.0.0.1:12345 test.out +V

In a different terminal, I use netcat to test (because the "send" support is not yet written).
  cat test.binary | netcat 127.0.0.1 12345

Use control-c to terminate TacocaT.

I can then confirm that the file has been created successfully via a md5sum check.
  md5sum test.out 0.6/specifications/fss-000f.txt

The checksums should match, and in my testing they do match.

12 files changed:
sources/c/tacocat/main/common.c
sources/c/tacocat/main/common/define.h
sources/c/tacocat/main/common/enumeration.h
sources/c/tacocat/main/common/print.c
sources/c/tacocat/main/common/print.h
sources/c/tacocat/main/common/type.c
sources/c/tacocat/main/common/type.h
sources/c/tacocat/main/print/error.c
sources/c/tacocat/main/print/error.h
sources/c/tacocat/main/process.c
sources/c/tacocat/main/receive.c
sources/c/tacocat/main/receive.h

index a471c97c66c02b3322ba5aec345e1a6b6e449a99..ec75ac068ba15506b46c3fd8b533102aa6715ddb 100644 (file)
@@ -310,42 +310,39 @@ extern "C" {
           sets[i]->statuss.array[j] = F_okay;
           sets[i]->flags.array[j] = kt_tacocat_socket_flag_none_e;
           sets[i]->retrys.array[j] = 0;
-          sets[i]->totals.array[j] = 0;
-          sets[i]->names.array[j].used = 0;
+          sets[i]->networks.array[j].used = 0;
           sets[i]->buffers.array[j].used = 0;
-          sets[i]->packets.array[j].control.start = 1;
-          sets[i]->packets.array[j].control.stop = 0;
-          sets[i]->packets.array[j].size.start = 1;
-          sets[i]->packets.array[j].size.stop = 0;
+          sets[i]->packets.array[j].control = 0;
+          sets[i]->packets.array[j].size = 0;
           sets[i]->packets.array[j].payload.start = 1;
           sets[i]->packets.array[j].payload.stop = 0;
 
           if (main->program.parameters.arguments.array[index].used) {
             if (f_path_is_absolute(main->program.parameters.arguments.array[index]) == F_true || f_path_is_relative_current(main->program.parameters.arguments.array[index]) == F_true) {
 
-              main->setting.state.status = f_memory_array_increase_by(main->program.parameters.arguments.array[index].used + 2, sizeof(f_char_t), (void **) &sets[i]->names.array[j].string, &sets[i]->names.array[j].used, &sets[i]->names.array[j].size);
+              main->setting.state.status = f_memory_array_increase_by(main->program.parameters.arguments.array[index].used + 2, sizeof(f_char_t), (void **) &sets[i]->networks.array[j].string, &sets[i]->networks.array[j].used, &sets[i]->networks.array[j].size);
 
               macro_setting_load_handle_send_receive_error_continue_2(f_memory_array_increase_by);
 
-              main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &sets[i]->names.array[j]);
+              main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &sets[i]->networks.array[j]);
 
               macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append_nulless);
 
               // Designate this as a socket file by appending after the terminating NULL, past the used length.
-              sets[i]->names.array[j].string[sets[i]->names.array[j].used] = 0;
-              sets[i]->names.array[j].string[sets[i]->names.array[j].used + 1] = f_string_ascii_slash_forward_s.string[0];
+              sets[i]->networks.array[j].string[sets[i]->networks.array[j].used] = 0;
+              sets[i]->networks.array[j].string[sets[i]->networks.array[j].used + 1] = f_string_ascii_slash_forward_s.string[0];
 
               if (is_receive[i]) {
-                main->setting.state.status = f_file_exists(sets[i]->names.array[j], F_true);
+                main->setting.state.status = f_file_exists(sets[i]->networks.array[j], F_true);
 
                 macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append_nulless);
               }
 
-              sets[i]->names.array[j].string[sets[i]->names.array[j].used] = 0;
+              sets[i]->networks.array[j].string[sets[i]->networks.array[j].used] = 0;
               sets[i]->sockets.array[j].domain = f_socket_protocol_family_local_e;
               sets[i]->sockets.array[j].protocol = f_socket_protocol_tcp_e;
               sets[i]->sockets.array[j].type = f_socket_type_stream_e;
-              sets[i]->sockets.array[j].name = sets[i]->names.array[j];
+              sets[i]->sockets.array[j].name = sets[i]->networks.array[j];
             }
             else if (main->setting.flag & kt_tacocat_main_flag_resolve_classic_e) {
               memset(&host, 0, sizeof(struct hostent));
@@ -404,7 +401,7 @@ extern "C" {
               }
 
               if (host.h_addrtype) {
-                main->setting.state.status = f_string_dynamic_append(address, &sets[i]->names.array[j]);
+                main->setting.state.status = f_string_dynamic_append(address, &sets[i]->networks.array[j]);
 
                 macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append);
               }
@@ -432,7 +429,7 @@ extern "C" {
                   continue;
                 }
 
-                main->setting.state.status = f_memory_array_increase_by(INET6_ADDRSTRLEN + 1, sizeof(f_char_t), (void **) &sets[i]->names.array[j].string, &sets[i]->names.array[j].used, &sets[i]->names.array[j].size);
+                main->setting.state.status = f_memory_array_increase_by(INET6_ADDRSTRLEN + 1, sizeof(f_char_t), (void **) &sets[i]->networks.array[j].string, &sets[i]->networks.array[j].used, &sets[i]->networks.array[j].size);
 
                 macro_setting_load_handle_send_receive_error_continue_2(f_memory_array_increase_by);
 
@@ -450,7 +447,7 @@ extern "C" {
                   k = 0;
                 }
 
-                main->setting.state.status = f_memory_array_increase_by(INET6_ADDRSTRLEN + 1, sizeof(f_char_t), (void **) &sets[i]->names.array[j].string, &sets[i]->names.array[j].used, &sets[i]->names.array[j].size);
+                main->setting.state.status = f_memory_array_increase_by(INET6_ADDRSTRLEN + 1, sizeof(f_char_t), (void **) &sets[i]->networks.array[j].string, &sets[i]->networks.array[j].used, &sets[i]->networks.array[j].size);
 
                 macro_setting_load_handle_send_receive_error_continue_2(f_memory_array_increase_by);
 
@@ -463,7 +460,7 @@ extern "C" {
                   family.address.v6 = *((struct in6_addr *) host.h_addr_list[k]);
                 }
 
-                main->setting.state.status = f_network_to_ip_string(family, &sets[i]->names.array[j]);
+                main->setting.state.status = f_network_to_ip_string(family, &sets[i]->networks.array[j]);
 
                 if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) {
                   main->setting.state.status = F_status_set_error(F_parameter);
@@ -482,7 +479,7 @@ extern "C" {
                   continue;
                 }
 
-                sets[i]->names.array[j].string[sets[i]->names.array[j].used] = 0;
+                sets[i]->networks.array[j].string[sets[i]->networks.array[j].used] = 0;
               }
 
               sets[i]->sockets.array[j].protocol = f_socket_protocol_tcp_e;
@@ -506,7 +503,7 @@ extern "C" {
             ++sets[i]->buffers.used;
             ++sets[i]->files.used;
             ++sets[i]->flags.used;
-            ++sets[i]->names.used;
+            ++sets[i]->networks.used;
             ++sets[i]->packets.used;
             ++sets[i]->polls.used;
             ++sets[i]->sockets.used;
@@ -603,13 +600,12 @@ extern "C" {
     set->buffers.used = 0;
     set->files.used = 0;
     set->flags.used = 0;
-    set->names.used = 0;
+    set->networks.used = 0;
     set->packets.used = 0;
     set->polls.used = 0;
     set->retrys.used = 0;
     set->sockets.used = 0;
     set->statuss.used = 0;
-    set->totals.used = 0;
 
     if (!set) {
       main->setting.state.status = F_status_set_error(F_parameter);
@@ -636,7 +632,7 @@ extern "C" {
     }
 
     if (F_status_is_error_not(main->setting.state.status)) {
-      main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_string_dynamic_t), (void **) &set->names.array, &set->names.used, &set->names.size);
+      main->setting.state.status = f_memory_array_increase_by(total, sizeof(f_string_dynamic_t), (void **) &set->networks.array, &set->networks.used, &set->networks.size);
     }
 
     if (F_status_is_error_not(main->setting.state.status)) {
@@ -652,10 +648,6 @@ extern "C" {
     }
 
     if (F_status_is_error_not(main->setting.state.status)) {
-      main->setting.state.status = f_memory_array_increase_by(total, sizeof(uint32_t), (void **) &set->totals.array, &set->totals.used, &set->totals.size);
-    }
-
-    if (F_status_is_error_not(main->setting.state.status)) {
       main->setting.state.status = F_okay;
     }
   }
index 232f8aed764ac1e06f33408a5f649c4615b7c018..6087f33db9a3c849852205aa9138a1b6a6cf15ef 100644 (file)
@@ -95,12 +95,11 @@ extern "C" {
  *   The same as macro_setting_load_handle_send_receive_error_continue_1() but intended for file errors.
  *
  * macro_kt_receive_process_handle_error_exit_1:
- *   Intended to be used for handling an error during the receive process while processing within flag kt_tacocat_socket_flag_block_begin_e.
+ *   Intended to be used for handling an error during the receive process while not processing within flag kt_tacocat_socket_flag_block_control_e.
  *   The parameter id_data and is set to 0 to disable and is otherwise an address pointer.
  *
- * macro_kt_receive_process_handle_error_exit_2:
- *   Intended to be used for handling an error during the receive process while not processing within flag kt_tacocat_socket_flag_block_begin_e.
- *   The parameter id_data and is set to 0 to disable and is otherwise an address pointer.
+ * macro_kt_receive_process_begin_handle_error_exit_1:
+ *   Intended to be used for handling an error during the receive process while processing within flag kt_tacocat_socket_flag_block_control_e.
  */
 #ifndef _di_kt_tacocat_macros_d_
   #define macro_setting_load_print_first() \
@@ -151,7 +150,6 @@ extern "C" {
       continue; \
     }
 
-  // @todo handle error, perform memory clearing and possibly send try again message to client but for now, just close the connection gracefully.
   #define macro_kt_receive_process_handle_error_exit_1(main, method, name, status, flag, id_data) \
     if (F_status_is_error(*status)) { \
       kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, *name, *status); \
@@ -160,26 +158,20 @@ extern "C" {
         f_file_close_id(id_data); \
       } \
       \
-      *flag -= kt_tacocat_socket_flag_block_begin_e; \
+      flag -= flag & kt_tacocat_socket_flag_block_control_e; \
+      flag -= flag & kt_tacocat_socket_flag_block_payload_e; \
       \
       return; \
     }
 
-    // @todo handle error, perform memory clearing and possibly send try again message to client but for now, just close the connection gracefully.
-    #define macro_kt_receive_process_handle_error_exit_2(main, method, name, status, flag, id_data) \
-      if (F_status_is_error(*status)) { \
-        kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, *name, *status); \
-        \
-        if (id_data) { \
-          f_file_close_id(id_data); \
-        } \
-        \
-        *flag -= *flag & kt_tacocat_socket_flag_block_begin_e; \
-        *flag -= *flag & kt_tacocat_socket_flag_block_control_e; \
-        *flag -= *flag & kt_tacocat_socket_flag_block_payload_e; \
-        \
-        return; \
-      }
+  #define macro_kt_receive_process_begin_handle_error_exit_1(main, method, name, status, flag) \
+    if (F_status_is_error(*status)) { \
+      kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, *name, *status); \
+      \
+      *flag -= kt_tacocat_socket_flag_block_control_e; \
+      \
+      return; \
+    }
 #endif // _di_kt_tacocat_macro_d_
 
 #ifdef __cplusplus
index eee8aa66f39cdb66db209913931cb8c5e7064293..b54688ef247183ab0fba52dfb4bb86821f5662e1 100644 (file)
@@ -131,16 +131,14 @@ extern "C" {
  *
  * kt_tacocat_socket_flag_*_e:
  *   - none:          No flags set.
- *   - block_begin:   The control block is ready to be read (but has not been fully ready yet).
- *   - block_control: The control block is fully read.
- *   - block_payload: The payload block is fully read.
+ *   - block_control: Reading and processing the Control block and Size block.
+ *   - block_payload: Reading and processing the Payload block.
  */
 #ifndef _di_kt_tacocat_socket_flag_e_
   enum {
     kt_tacocat_socket_flag_none_e          = 0x0,
-    kt_tacocat_socket_flag_block_begin_e   = 0x1,
-    kt_tacocat_socket_flag_block_control_e = 0x2,
-    kt_tacocat_socket_flag_block_payload_e = 0x4,
+    kt_tacocat_socket_flag_block_control_e = 0x1,
+    kt_tacocat_socket_flag_block_payload_e = 0x2,
   }; // enum
 #endif // _di_kt_tacocat_socket_flag_e_
 
index 6553719fbad662ae78a80f5027d9dcbbe2d1d4c6..e928c477063a6e88e48720251911c57bbd6d747d 100644 (file)
@@ -9,7 +9,8 @@ extern "C" {
     "f_console_parameter_process",
     "f_file_close_id",
     "f_file_open",
-    "f_fss_simple_packet_identify",
+    "f_file_write",
+    "f_fss_simple_packet_extract_range",
     "f_memory_array_increase_by",
     "f_memory_array_resize",
     "f_network_from_ip_name",
index b1a4e309987c3b1c78bca3824e234be4a4df2322..f4eea476a1e57fea9ec07446215bf654ea1847d3 100644 (file)
@@ -42,7 +42,8 @@ extern "C" {
     kt_tacocat_f_f_console_parameter_process_e,
     kt_tacocat_f_f_file_close_id_e,
     kt_tacocat_f_f_file_open_e,
-    kt_tacocat_f_f_fss_simple_packet_identify_e,
+    kt_tacocat_f_f_file_write_e,
+    kt_tacocat_f_f_fss_simple_packet_extract_range_e,
     kt_tacocat_f_f_memory_array_increase_by_e,
     kt_tacocat_f_f_memory_array_resize_e,
     kt_tacocat_f_f_network_from_ip_name_e,
index c20ef6630db3ed2a338ce7ed911c4fb3ab07296d..a0e7a330112cc40e91b9c71392519f139d6454d5 100644 (file)
@@ -43,12 +43,11 @@ extern "C" {
 
         f_memory_array_resize(0, sizeof(uint16_t), (void **) &sets[i]->flags.array, &sets[i]->flags.used, &sets[i]->flags.size);
         f_memory_array_resize(0, sizeof(uint16_t), (void **) &sets[i]->retrys.array, &sets[i]->retrys.used, &sets[i]->retrys.size);
-        f_memory_array_resize(0, sizeof(uint32_t), (void **) &sets[i]->totals.array, &sets[i]->totals.used, &sets[i]->totals.size);
         f_memory_array_resize(0, sizeof(f_file_t), (void **) &sets[i]->files.array, &sets[i]->files.used, &sets[i]->files.size);
         f_memory_array_resize(0, sizeof(f_poll_t), (void **) &sets[i]->polls.array, &sets[i]->polls.used, &sets[i]->polls.size);
         f_memory_array_resize(0, sizeof(f_socket_t), (void **) &sets[i]->sockets.array, &sets[i]->sockets.used, &sets[i]->sockets.size);
         f_memory_array_resize(0, sizeof(f_status_t), (void **) &sets[i]->statuss.array, &sets[i]->statuss.used, &sets[i]->statuss.size);
-        f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &sets[i]->names.array, &sets[i]->names.used, &sets[i]->names.size, &f_string_dynamics_delete_callback);
+        f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &sets[i]->networks.array, &sets[i]->networks.used, &sets[i]->networks.size, &f_string_dynamics_delete_callback);
         f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &sets[i]->buffers.array, &sets[i]->buffers.used, &sets[i]->buffers.size, &f_string_dynamics_delete_callback);
         f_memory_array_resize(0, sizeof(f_fss_simple_packet_range_t), (void **) &sets[i]->packets.array, &sets[i]->packets.used, &sets[i]->packets.size);
       } // for
index fe8da645a237523cc982c18c8612a4926e711de9..418e230721567a8e22c12028b925686ead975c65 100644 (file)
@@ -24,15 +24,14 @@ extern "C" {
  *
  * flags:   An array of flags for each socket.
  * retrys:  An array of the current number of retries performed for the given network packet.
- * totals:  An array of the total network stream size accoding to the processed packet.
  * files:   An array of files for each socket.
  * polls:   An array of sockets to poll, specifically for passing to f_file_poll().
  * sockets: An array of the network sockets.
  * statuss: An array of statuses for each socket.
  *
- * names:   An array of names for each socket.
- * buffers: An array of buffers for sending or receiving data between clients for each socket.
- * packets: An array of simple packet ranges representing the parts of the packet for each socket for use during processing.
+ * networks: An array of networks for each socket.
+ * buffers:  An array of buffers for sending or receiving data between clients for each socket.
+ * packets:  An array of simple packet ranges representing the parts of the packet for each socket for use during processing.
  */
 #ifndef _di_kt_tacocat_socket_set_t_
   typedef struct {
@@ -40,13 +39,12 @@ extern "C" {
 
     f_uint16s_t flags;
     f_uint16s_t retrys;
-    f_uint32s_t totals;
     f_files_t files;
     f_polls_t polls;
     f_sockets_t sockets;
     f_statuss_t statuss;
 
-    f_string_dynamics_t names;
+    f_string_dynamics_t networks;
     f_string_dynamics_t buffers;
     f_fss_simple_packet_ranges_t packets;
   } kt_tacocat_socket_set_t;
@@ -56,7 +54,6 @@ extern "C" {
       kt_tacocat_block_size_d, \
       f_uint16s_t_initialize, \
       f_uint16s_t_initialize, \
-      f_uint32s_t_initialize, \
       f_files_t_initialize, \
       f_polls_t_initialize, \
       f_sockets_t_initialize, \
@@ -71,7 +68,6 @@ extern "C" {
       size_block, \
       f_uint16s_t_initialize, \
       f_uint16s_t_initialize, \
-      f_uint32s_t_initialize, \
       f_files_t_initialize, \
       f_polls_t_initialize, \
       f_sockets_t_initialize, \
index a759af77cdb90da61422a260f8ec8187e8d787dc..9f519036c751b6152b7146bd60e101061ed8ae61 100644 (file)
@@ -63,7 +63,7 @@ extern "C" {
 #endif // _di_kt_tacocat_print_error_
 
 #ifndef _di_kt_tacocat_print_error_on_buffer_too_large_
-  f_status_t kt_tacocat_print_error_on_buffer_too_large(fl_print_t * const print, f_string_static_t on, const f_string_static_t network) {
+  f_status_t kt_tacocat_print_error_on_buffer_too_large(fl_print_t * const print, f_string_static_t on, const f_string_static_t network, const f_number_unsigned_t size_expect, const f_number_unsigned_t size_got) {
 
     if (!print) return F_status_set_error(F_output_not);
     if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
@@ -74,7 +74,11 @@ extern "C" {
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
     fl_print_format(" %[buffer for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
-    fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
+    fl_print_format("%[', the maximum size is%] ", print->to, print->set->error, print->set->error);
+    fl_print_format("%[%ul%]", print->to, print->set->notable, size_expect, print->set->notable);
+    fl_print_format("%[, and the provided size is%] ", print->to, print->set->error, print->set->error);
+    fl_print_format("%[%ul%]", print->to, print->set->notable, size_got, print->set->notable);
+    fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
 
     f_file_stream_unlock(print->to);
 
@@ -102,6 +106,28 @@ extern "C" {
   }
 #endif // _di_kt_tacocat_print_error_on_busy_
 
+#ifndef _di_kt_tacocat_print_error_on_file_
+  f_status_t kt_tacocat_print_error_on_file(fl_print_t * const print, const f_string_t function, f_string_static_t on, const f_string_static_t network, const f_status_t status, const f_string_static_t name) {
+
+    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);
+
+    fl_print_format("%[%QNetwork on%] ", print->to, print->set->error, print->prefix, print->set->error);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
+    fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
+    fl_print_format("%[' failed to write to file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
+    fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+
+    fll_error_file_print(print, F_status_set_fine(((kt_tacocat_main_t *) print->custom)->setting.state.status), function, F_true, name, f_file_operation_write_s, fll_error_file_type_file_e);
+  }
+#endif // _di_kt_tacocat_print_error_on_file_
+
 #ifndef _di_kt_tacocat_print_error_on_packet_too_small_
   f_status_t kt_tacocat_print_error_on_packet_too_small(fl_print_t * const print, f_string_static_t on, const f_string_static_t network, const f_number_unsigned_t size_expect, const f_number_unsigned_t size_got) {
 
@@ -183,7 +209,7 @@ extern "C" {
     fl_print_format("%[%QThe lengths of all%] ", print->to, print->set->error, print->prefix, print->set->error);
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
     fl_print_format(" %[arrays do not have the same length, name array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
-    fl_print_format("%[%ul%]", print->to, print->set->notable, set.names.used, print->set->notable);
+    fl_print_format("%[%ul%]", print->to, print->set->notable, set.networks.used, print->set->notable);
     fl_print_format("%', the buffer array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
     fl_print_format("%[%ul%]", print->to, print->set->notable, set.buffers.used, print->set->notable);
     fl_print_format("%', the file array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
index 0800437ce8bdb06003afe69f8506a5423434f335..9742480ba85a6397cdc611b54e601525b7d2f3bb 100644 (file)
@@ -135,6 +135,10 @@ extern "C" {
  *   The network connection direction, which should either be "receive" or "send".
  * @param network
  *   The name of the network in which the error is related.
+ * @param size_max
+ *   The maximum buffer size.
+ * @param size_got
+ *   The provided buffer size.
  *
  * @return
  *   F_okay on success.
@@ -145,7 +149,7 @@ extern "C" {
  * @see fll_error_file_print()
  */
 #ifndef _di_kt_tacocat_print_error_on_buffer_too_large_
-  extern f_status_t kt_tacocat_print_error_on_buffer_too_large(fl_print_t * const print, f_string_static_t on, const f_string_static_t network);
+  extern f_status_t kt_tacocat_print_error_on_buffer_too_large(fl_print_t * const print, f_string_static_t on, const f_string_static_t network, const f_number_unsigned_t size_expect, const f_number_unsigned_t size_got);
 #endif // _di_kt_tacocat_print_error_on_buffer_too_large_
 
 /**
@@ -171,6 +175,36 @@ extern "C" {
 #ifndef _di_kt_tacocat_print_error_on_busy_
   extern f_status_t kt_tacocat_print_error_on_busy(fl_print_t * const print, f_string_static_t on, const f_string_static_t network);
 #endif // _di_kt_tacocat_print_error_on_busy_
+/**
+ * Print network-related error message regarding the writing the network data to a file.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param function
+ *   The name of the function where the error happened.
+ *   Set to 0 to disable.
+ * @param on
+ *   The network connection direction, which should either be "receive" or "send".
+ * @param network
+ *   The name of the network in which the error is related.
+ * @param status
+ *   The status code representing the error.
+ * @param name
+ *   The name of the file or directory.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_file_print()
+ */
+#ifndef _di_kt_tacocat_print_error_on_file_
+  extern f_status_t kt_tacocat_print_error_on_file(fl_print_t * const print, const f_string_t function, f_string_static_t on, const f_string_static_t network, const f_status_t status, const f_string_static_t name);
+#endif // _di_kt_tacocat_print_error_on_file_
 
 /**
  * Print network-related error message for when the connection is busy.
@@ -184,9 +218,9 @@ extern "C" {
  * @param network
  *   The name of the network in which the error is related.
  * @param size_expect
- *   The expected packet size.
+ *   The expected buffer size.
  * @param size_got
- *   The packet size that is received.
+ *   The provided buffer size.
  *
  * @return
  *   F_okay on success.
index 68ab129d8f26010fab81ab5c76b54e1a5b022d88..ef28e39b109361dd0ceeb1eb6c0e80c18ee19c5c 100644 (file)
@@ -127,7 +127,7 @@ extern "C" {
       return F_status_set_error(F_parameter);
     }
 
-    if (set.sockets.used != set.files.used || set.sockets.used != set.files.used || set.sockets.used != set.statuss.used || set.sockets.used != set.names.used || set.sockets.used != set.buffers.used) {
+    if (set.sockets.used != set.files.used || set.sockets.used != set.files.used || set.sockets.used != set.statuss.used || set.sockets.used != set.networks.used || set.sockets.used != set.buffers.used) {
       *status = F_status_set_error(F_parameter);
 
       kt_tacocat_print_error_setting_socket_lengths_must_match(&main->program.error, parameter, set);
@@ -151,6 +151,9 @@ extern "C" {
       if (kt_tacocat_signal_check(main)) return;
       if (F_status_is_error(main->setting.receive.statuss.array[i])) continue;
 
+      main->setting.receive.sockets.array[i].id = -1;
+      main->setting.receive.sockets.array[i].id_data = -1;
+
       main->setting.receive.statuss.array[i] = f_socket_create(&main->setting.receive.sockets.array[i]);
 
       if (F_status_is_error(main->setting.receive.statuss.array[i])) {
@@ -190,14 +193,14 @@ extern "C" {
         else {
           main->setting.status_receive = F_status_set_error(F_parameter);
 
-          kt_tacocat_print_error_socket_protocol_unsupported(&main->program.error, main->setting.receive.names.array[i], main->setting.receive.sockets.array[i].domain);
+          kt_tacocat_print_error_socket_protocol_unsupported(&main->program.error, main->setting.receive.networks.array[i], main->setting.receive.sockets.array[i].domain);
 
           return;
         }
 
         if (F_status_set_fine(main->setting.receive.statuss.array[i]) == F_busy_address) {
           if (main->setting.receive.retrys.array[i] < kt_tacocat_startup_retry_max_d) {
-            kt_tacocat_print_warning_on_busy(&main->program.warning, kt_tacocat_receive_s, main->setting.receive.names.array[i], main->setting.receive.retrys.array[i] + 1);
+            kt_tacocat_print_warning_on_busy(&main->program.warning, kt_tacocat_receive_s, main->setting.receive.networks.array[i], main->setting.receive.retrys.array[i] + 1);
 
             struct timespec time = { 0 };
 
@@ -232,7 +235,7 @@ extern "C" {
         main->setting.status_receive = main->setting.receive.statuss.array[i];
 
         if (F_status_set_fine(main->setting.status_receive) == F_busy_address) {
-          kt_tacocat_print_error_on_busy(&main->program.error, kt_tacocat_receive_s, main->setting.receive.names.array[i]);
+          kt_tacocat_print_error_on_busy(&main->program.error, kt_tacocat_receive_s, main->setting.receive.networks.array[i]);
         }
         else {
           kt_tacocat_print_error_status(&main->program.error, main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_inet4_e
index 29f2be257433d108b0292ef71b1877f57843a9f2..a56601309dccb9c7ba659446f4263baea7307761 100644 (file)
@@ -40,12 +40,6 @@ extern "C" {
               if (F_status_is_error(main->setting.state.status)) continue;
             }
           } // for
-
-          // @todo handle errors
-          //if (F_status_is_error(main->setting.receive.statuss.array[i])) ... // @todo more work needed to clear error bit when a new read is ready.
-        }
-        else {
-          // @todo handle error or F_time_out on main->setting.status_receive.
         }
 
       } while (F_status_is_error_not(main->setting.status_receive));
@@ -66,167 +60,195 @@ extern "C" {
 #ifndef _di_kt_tacocat_receive_process_
   void kt_tacocat_receive_process(kt_tacocat_main_t * const main, const f_number_unsigned_t index) {
 
-    uint16_t * const flag = &main->setting.receive.flags.array[index];
-    uint16_t * const retry = &main->setting.receive.retrys.array[index];
-    uint32_t * const total = &main->setting.receive.totals.array[index];
-    f_poll_t * const poll = &main->setting.receive.polls.array[index];
+    if (!main) return;
+
     f_socket_t * const socket = &main->setting.receive.sockets.array[index];
     f_status_t * const status = &main->setting.receive.statuss.array[index];
-    f_string_dynamic_t * const name = &main->setting.receive.names.array[index];
+    f_string_dynamic_t * const network = &main->setting.receive.networks.array[index];
     f_string_dynamic_t * const buffer = &main->setting.receive.buffers.array[index];
     f_fss_simple_packet_range_t * const packet = &main->setting.receive.packets.array[index];
 
-    size_t length_read = 0;
-
     // This is a new packet (kt_tacocat_socket_flag_none_e).
-    if (!(*flag)) {
-      *flag = kt_tacocat_socket_flag_block_begin_e;
-      *retry = 0;
-      *total = 0;
+    if (!(main->setting.receive.flags.array[index])) {
+      main->setting.receive.flags.array[index] = kt_tacocat_socket_flag_block_control_e;
+      main->setting.receive.retrys.array[index] = 0;
       buffer->used = 0;
       socket->size_read = kt_tacocat_packet_read_d;
     }
 
-    const size_t size_read = socket->size_read;
-
-    // @todo move this section into its own function call.
     // Load the header of the new packet.
-    if ((*flag) & kt_tacocat_socket_flag_block_begin_e) {
-      *status = f_socket_accept(socket);
+    if (main->setting.receive.flags.array[index] & kt_tacocat_socket_flag_block_control_e) {
+      kt_tacocat_receive_process_control(main, index);
 
-      // The socket failed to accept and so there is no data socket id to close.
-      macro_kt_receive_process_handle_error_exit_1(main, f_socket_accept, name, status, flag, 0);
+      if (F_status_is_error(*status) || buffer->used < kt_tacocat_packet_peek_d) {
+        f_file_close_id(&socket->id_data);
 
-      *status = f_memory_array_increase_by(kt_tacocat_packet_peek_d + 1, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
-      macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, name, status, flag, &socket->id_data);
+        return;
+      }
 
-      socket->size_read = kt_tacocat_packet_peek_d;
+      // Reset the buffer to allow for reusing and writing to the file in blocks.
+      buffer->used = 0;
+      socket->size_read = kt_tacocat_packet_read_d;
 
-      *status = f_socket_read_stream(socket, 0, (void *) (buffer->string + buffer->used), &length_read);
+      // Make sure the buffer is large enough for payload processing block reads.
+      *status = f_memory_array_increase_by(socket->size_read, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
+      macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, network, status, main->setting.receive.flags.array[index], &socket->id_data);
+    }
 
-      socket->size_read = size_read;
+    if (main->setting.receive.flags.array[index] & kt_tacocat_socket_flag_block_payload_e) {
+      size_t length_read = 0;
 
-      macro_kt_receive_process_handle_error_exit_1(main, f_socket_read_stream, name, status, flag, &socket->id_data);
+      *status = f_socket_read_stream(socket, 0, (void *) buffer->string, &length_read);
+      macro_kt_receive_process_handle_error_exit_1(main, f_socket_read_stream, network, status, main->setting.receive.flags.array[index], &socket->id_data);
 
-      buffer->used += length_read;
+      if (length_read) {
+        buffer->used = length_read;
 
-      // Continue if the packet header is not fully ready (@todo, implement a counter with a max length thaat prevents infinite loop waits, "retry" is intended for this).
-      if (buffer->used < kt_tacocat_packet_peek_d) {
+        *status = f_file_write(main->setting.receive.files.array[index], *buffer, 0);
 
-        // Peek ahead to see if the client has closed the connection (all the intended data should have been transmitted).
-        if (length_read) {
-          memset(main->cache.peek, 0, kt_tacocat_cache_size_peek_d);
+        // Keep going on error, but in the future more advanced error handling/recovery is needed to make this more robust.
+        if (F_status_is_error(*status)) {
+          // @fixme The file name is not being saved, need to add the file name. For now just adding "socket->name" as a placeholder.
+          kt_tacocat_print_error_on_file(&main->program.error, macro_kt_tacocat_f(f_file_write), kt_tacocat_receive_s, *network, *status, socket->name);
+        }
 
-          socket->size_read = kt_tacocat_cache_size_peek_d - 1;
-          length_read = 0;
+        // Reset buffer used and increment counter.
+        main->setting.receive.packets.array[index].payload.stop += buffer->used;
+        buffer->used = 0;
 
-          *status = f_socket_read_stream(socket, f_socket_flag_peek_e | f_socket_flag_wait_not_e, (void *) main->cache.peek, &length_read);
+        f_file_close_id(&socket->id_data);
 
-          socket->size_read = size_read;
-        }
+        if (main->setting.receive.packets.array[index].payload.stop < main->setting.receive.packets.array[index].size) return;
+      }
 
-        // Connection is closed when length is 0, which means the packet is too small.
-        if (!length_read) {
-          kt_tacocat_print_error_on_packet_too_small(&main->program.error, kt_tacocat_receive_s, *name, kt_tacocat_packet_peek_d, buffer->used);
+      main->setting.receive.flags.array[index] -= kt_tacocat_socket_flag_block_payload_e;
+    }
 
-          buffer->used = 0;
-          *retry = 0;
-          *status = F_status_set_error(F_packet_too_small);
-          *flag -= kt_tacocat_socket_flag_block_begin_e;
+    // Done processing the Packet.
+    f_file_close_id(&socket->id_data);
+    main->setting.receive.flags.array[index] = 0;
 
-          f_file_close_id(&socket->id_data);
+    if (buffer->size > kt_tacocat_max_maintain_d) {
+      buffer->used = 0;
 
-          return;
-        }
+      *status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
 
-        ++(*retry);
+      // Report the resize error but do not fail.
+      if (F_status_is_error(*status)) {
+        kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, *network, *status);
+      }
+    }
+  }
+#endif // _di_kt_tacocat_receive_process_
 
-        f_file_close_id(&socket->id_data);
+#ifndef _di_kt_tacocat_receive_process_control_
+  void kt_tacocat_receive_process_control(kt_tacocat_main_t * const main, const f_number_unsigned_t index) {
 
-        return;
-      }
+    if (!main) return;
 
-      packet->control.start = 1;
-      packet->control.stop = 0;
-      packet->size.start = 1;
-      packet->size.stop = 0;
-      packet->payload.start = 1;
-      packet->payload.stop = 0;
+    uint16_t * const flag = &main->setting.receive.flags.array[index];
+    f_socket_t * const socket = &main->setting.receive.sockets.array[index];
+    f_status_t * const status = &main->setting.receive.statuss.array[index];
+    f_string_dynamic_t * const network = &main->setting.receive.networks.array[index];
+    f_string_dynamic_t * const buffer = &main->setting.receive.buffers.array[index];
 
-      // @todo need to check/handle if all of the parts exists (want F_okay, but check F_partial, F_data_not, and F_valid_not (F_valid_not has error bit set).
-      *status = f_fss_simple_packet_identify(*buffer, packet);
-      macro_kt_receive_process_handle_error_exit_1(main, f_fss_simple_packet_identify, name, status, flag, &socket->id_data);
+    const size_t size_read = socket->size_read;
+    size_t length_read = 0;
 
-      // @todo this needs to be wrapped in big/little endian checks, but for now just use ntohl.
-      *total = ntohl(*((uint32_t *) (buffer->string + 1)));
+    *status = f_socket_accept(socket);
 
-      if (*total <= F_fss_simple_packet_block_header_size_d) {
-        // @todo handle error, perform memory clearing and possibly send try again message to client but for now, just close the connection gracefully.
-        f_file_close_id(&socket->id_data);
+    // The socket failed to accept and so there is no data socket id to close.
+    macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_accept, network, status, flag);
 
-        *flag -= kt_tacocat_socket_flag_block_begin_e;
+    *status = f_memory_array_increase_by(kt_tacocat_packet_peek_d + 1, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
+    macro_kt_receive_process_begin_handle_error_exit_1(main, f_memory_array_increase_by, network, status, flag);
 
-        return;
-      }
+    socket->size_read = kt_tacocat_packet_peek_d;
 
-      if (main->setting.flag & kt_tacocat_main_flag_max_buffer_e) {
-        if (*total > main->setting.max_buffer) {
-          buffer->used = 0;
+    *status = f_socket_read_stream(socket, 0, (void *) (buffer->string + buffer->used), &length_read);
 
-          if (buffer->size > kt_tacocat_max_maintain_d) {
-            *status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
+    socket->size_read = size_read;
 
-            // Report the resize error but do not fail.
-            if (F_status_is_error(*status)) {
-              kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, *name, *status);
-            }
-          }
+    macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_read_stream, network, status, flag);
 
-          // @todo for all unrecoverable errors, make sure to drop/flush the packet to prevent processing and then reset the status code (otherwise an infinite error loop will occur, which is the current behavior).
-          *status = F_status_set_error(F_packet_too_large);
+    buffer->used += length_read;
 
-          kt_tacocat_print_error_on_buffer_too_large(&main->program.error, kt_tacocat_receive_s, *name); // @todo pass total parameter to print requested packet size.
+    // Continue if the packet header is not fully ready.
+    if (buffer->used < kt_tacocat_packet_peek_d) {
 
-          // @todo send message to client that the packet is too large but for now, just close the connection gracefully.
-          f_file_close_id(&socket->id_data);
+      // Peek ahead to see if the client has closed the connection (all the intended data should have been transmitted).
+      if (length_read) {
+        memset(main->cache.peek, 0, kt_tacocat_cache_size_peek_d);
 
-          return;
-        }
+        socket->size_read = kt_tacocat_cache_size_peek_d - 1;
+        length_read = 0;
+
+        *status = f_socket_read_stream(socket, f_socket_flag_peek_e | f_socket_flag_wait_not_e, (void *) main->cache.peek, &length_read);
+
+        socket->size_read = size_read;
+      }
+
+      // Connection is closed when length is 0, which means the packet is too small.
+      if (!length_read) {
+        kt_tacocat_print_error_on_packet_too_small(&main->program.error, kt_tacocat_receive_s, *network, kt_tacocat_packet_peek_d, buffer->used);
+
+        buffer->used = 0;
+        main->setting.receive.retrys.array[index] = 0;
+        *status = F_status_set_error(F_packet_too_small);
+        *flag = 0;
+
+        return;
       }
 
-      *flag -= kt_tacocat_socket_flag_block_begin_e;
-      *flag |= kt_tacocat_socket_flag_block_control_e;
+      ++main->setting.receive.retrys.array[index];
+
+      return;
     }
 
-    *status = f_memory_array_increase_by(socket->size_read, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
-    macro_kt_receive_process_handle_error_exit_2(main, f_memory_array_increase_by, name, status, flag, &socket->id_data);
+    *status = f_fss_simple_packet_extract_range(*buffer, &main->setting.receive.packets.array[index]);
+    macro_kt_receive_process_begin_handle_error_exit_1(main, f_fss_simple_packet_extract_range, network, status, flag);
 
-    *status = f_socket_read_stream(socket, f_socket_flag_wait_not_e, (void *) buffer->string, &length_read);
-    macro_kt_receive_process_handle_error_exit_2(main, f_socket_read_stream, name, status, flag, &socket->id_data);
+    if (*status == F_packet_too_small) {
+      main->setting.receive.packets.array[index].control = 0;
+      main->setting.receive.packets.array[index].size = 0;
+    }
 
-    //kt_tacocat_socket_flag_none_e          = 0x0,
-    //kt_tacocat_socket_flag_block_control_e = 0x1,
-    //kt_tacocat_socket_flag_block_payload_e = 0x2,
+    if (main->setting.receive.packets.array[index].size < F_fss_simple_packet_block_header_size_d) {
+      *flag = 0;
 
-    // f_socket_flag_peek_e,
-    //f_socket_read_stream
+      return;
+    }
 
-    // For now just close the socket until the appropriate code gets written here.
-    f_file_close_id(&socket->id_data);
+    if (main->setting.flag & kt_tacocat_main_flag_max_buffer_e) {
+      if (main->setting.receive.packets.array[index].size > main->setting.max_buffer) {
+        buffer->used = 0;
 
-    // @todo perform this check only when fully finished processing all of the packet parts (expected *total is reached).
-    if (buffer->size > kt_tacocat_max_maintain_d) {
-      buffer->used = 0;
+        if (buffer->size > kt_tacocat_max_maintain_d) {
+          *status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
 
-      *status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
+          // Report the resize error but do not fail.
+          if (F_status_is_error(*status)) {
+            kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, *network, *status);
+          }
+        }
 
-      // Report the resize error but do not fail.
-      if (F_status_is_error(*status)) {
-        kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, *name, *status);
+        *status = F_status_set_error(F_packet_too_large);
+        *flag = 0;
+
+        kt_tacocat_print_error_on_buffer_too_large(&main->program.error, kt_tacocat_receive_s, *network, main->setting.max_buffer, main->setting.receive.packets.array[index].size);
+
+        return;
       }
     }
+
+    *flag |= kt_tacocat_socket_flag_block_payload_e;
+    *flag -= kt_tacocat_socket_flag_block_control_e;
+
+    // The payload range "stop" is used to represent the total amount of bytes processed so far (uncluding the header).
+    main->setting.receive.packets.array[index].payload.start = 0;
+    main->setting.receive.packets.array[index].payload.stop = buffer->used - 1;
   }
-#endif // _di_kt_tacocat_receive_process_
+#endif // _di_kt_tacocat_receive_process_control_
 
 #ifdef __cplusplus
 } // extern "C"
index 000e9840a554436a83508596a70e52c115064009..0d3d887f43e6b4b15935848e5b8c5b1dd67ca889 100644 (file)
@@ -32,7 +32,7 @@ extern "C" {
 #endif // _di_kt_tacocat_receive_
 
 /**
- * Process the buffer, retrieving the data and writing to the file.
+ * Process the network socket, retrieving the data and writing to the file.
  *
  * @param main
  *   The main program and settings data.
@@ -51,6 +51,26 @@ extern "C" {
   extern void kt_tacocat_receive_process(kt_tacocat_main_t * const main, const f_number_unsigned_t index);
 #endif // _di_kt_tacocat_receive_process_
 
+/**
+ * Process the network socket, retrieving and processing the Control and Size header information.
+ *
+ * @param main
+ *   The main program and settings data.
+ *
+ *   This alters main.setting.state.status:
+ *     F_okay on success.
+ *
+ *     F_packet_too_large (with error bit) on total packet size is too large.
+ *     F_payload_too_large (with error bit) on total payload size is too large.
+ * @param index
+ *   The position within the receive arrays to process.
+ *
+ * @see f_socket_read_stream()
+ */
+#ifndef _di_kt_tacocat_receive_process_control_
+  extern void kt_tacocat_receive_process_control(kt_tacocat_main_t * const main, const f_number_unsigned_t index);
+#endif // _di_kt_tacocat_receive_process_control_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif