Start making room for handling the additional package parts, error packets, and all other packets.
Clean up some of the documentation and add tacocat package specific documentation.
# license: cc-by-sa-4.0
#
# This file (assumed to be named readme.build.txt) can be more easily read using the following iki_read commands:
-# iki_read readme.build.txt +Q -w -rr FLL FLL FSS FSS -WW character "'" "'" code '"' '"'
+# iki_read readme.build.txt +Q -w -rr FLL FLL FSS FSS -W code '"' '"'
#
# To read the "Build Readme Documentation" section of this file, use this command sequence:
-# fss_basic_list_read readme.build.txt +Q -cn "Build Readme Documentation" | iki_read +Q -w -rr FLL FLL FSS FSS -WW character "'" "'" code '"' '"'
+# fss_basic_list_read readme.build.txt +Q -cn "Build Readme Documentation" | iki_read +Q -w -rr FLL FLL FSS FSS -W code '"' '"'
#
Build Readme Documentation:
# license: cc-by-sa-4.0
#
# This file (assumed to be named readme.remove.txt) can be more easily read using the following iki_read commands:
-# iki_read readme.remove.txt +Q -w -r FLL FLL -WW character "'" "'" code '"' '"'
+# iki_read readme.remove.txt +Q -w -W code '"' '"'
#
# To read the "Remove Readme Documentation" section of this file, use this command sequence:
-# fss_basic_list_read readme.remove.txt +Q -cn "Remove Readme Documentation" | iki_read +Q -w -r FLL FLL -WW character "'" "'" code '"' '"'
+# fss_basic_list_read readme.remove.txt +Q -cn "Remove Readme Documentation" | iki_read +Q -w -W code '"' '"'
#
Remove Readme Documentation:
--- /dev/null
+# fss-0002 iki-0000
+#
+# license: cc-by-sa-4.0
+#
+# This file (assumed to be named readme.tacocat-packet.txt) can be more easily read using the following iki_read commands:
+# iki_read readme.tacocat-packet.txt +Q -w -r FLL FLL -W code '"' '"'
+#
+# To read the "TacocaT Packet Readme Documentation" section of this file, use this command sequence:
+# fss_basic_list_read readme.tacocat-packet.txt +Q -cn "TacocaT Packet Readme Documentation" | iki_read +Q -w -r FLL FLL -W code '"' '"'
+#
+
+TacocaT Packet Readme Documentation:
+ This describes the numerous bold:"tacocat" related network packets.
+
+ The bold:"packet" is designed around italic:"push" logic in that the sender shall push to the receiver to initiate the connection and transfer the file.
+ The receiver therefore cannot ask which part to work on.
+ However, the receiver can immediately issue a code:"next" bold:"packet" with the code:"part" at any given valid position within the range of the total bold:"packets".
+ To prevent abuse, the sender should have a maximum number of code:"next" and code:"resend" packets before aborting and must ensure that potential circular logic for the code:"next" bold:"packets" does not become a problem.
+
+ The following are the standard bold:"packet" headers and their purposes\:
+ - code:"status": This describes the status code of the bold:"packet" using FLL:"Featureless Linux Library" status codes (as strings rather than digits), such as code:"F_okay".
+ - code:"type": This describes the type of the bold:"packet", which is one of: code:"abort", code:"done", code:"file", code:"next", or code:"resend".
+ - code:"length": This describes the complete length of the code:"Payload" code:"Content" within the bold:"packet".
+ - code:"part": This describes the part within the sequence of total bold:"packets", starting at 0 rather than 1.
+ - code:"total": This describes the total number of sequence of packets needed to transmit an entire file.
+ - code:"name": This describes the name of the file being transmitted.
+ - code:"salt": This is a random sequence of printable characters used to make the bold:"packet" more unique should it be encrypted.
+
+ The code:"abort" bold:"packet" type is the bold:"packet" used for informing the other end to immediately abort the connection.
+ This uses the following headers: code:"status", code:"type", and code:"salt".
+ The sender should wait for a code:"done" bold:"packet" but may immediately abort rather than wait.
+ This is should not have a code:"Payload" section.
+
+ The code:"done" bold:"packet" type is the bold:"packet" used for informing the connection on the other end that this end of the connection is done with a particular transmission or action.
+ This uses the following headers: code:"status", code:"type", and code:"salt".
+ When the used in response to a code:"file" bold:"packet", this bold:"packet" represents that the file transfer is completely received.
+ The sender does not send a done bold:"packet" when transmitting a code:"file" bold:"packet".
+ This is should not have a code:"Payload" section.
+
+ The code:"file" bold:"packet" type is the bold:"packet" used for transmitting files from the sender to the receiver.
+ This uses the following headers: code:"status", code:"type", code:"length", code:"part", code:"total", code:"name", and code:"salt".
+ This is expected to have a code:"Payload" section defined, except when the code:"Payload" is of 0 length (an empty file).
+
+ The code:"next" bold:"packet" type is the bold:"packet" used for confirming that a bold:"packet" part has been received on the receiving end and the sender should send the next bold:"packet".
+ This uses the following headers: code:"status", code:"type", code:"part", code:"name", and code:"salt".
+ The sender should increment to the immediate next code:"part" by incrementing that part by one so long as that next part is within a valid range.
+ This is not sent for the last bold:"packet" by the receiver.
+ Should a receiver transmit a code:"next" packet once the total is reached, then the sender should inform the receiver of this error by responding with a code:"done" packet containing the code:"part" header set to the last valid part number (which is total minus one).
+ The code:"part" should represent the current part already read and now confirmed.
+ This is should not have a code:"Payload" section.
+
+ The code:"resend" bold:"packet" type is the bold:"packet" used for asking for an already sent bold:"packet".
+ This uses the following headers: code:"status", code:"type", code:"part", code:"name", and code:"salt".
+ The code:"part" should represent the part to be resent.
+ This is should not have a code:"Payload" section.
# license: cc-by-sa-4.0
#
# This file (assumed to be named readme.tacocat.txt) can be more easily read using the following iki_read commands:
-# iki_read readme.tacocat.txt +Q -w -rr FLL FLL DNS DNS -WW character "'" "'" code '"' '"'
+# iki_read readme.tacocat.txt +Q -w -rr FLL FLL DNS DNS -W code '"' '"'
#
# To read the "TacocaT Readme Documentation" section of this file, use this command sequence:
-# fss_basic_list_read readme.tacocat.txt +Q -cn "TacocaT Readme Documentation" | iki_read +Q -w -rr FLL FLL DNS DNS -WW character "'" "'" code '"' '"'
+# fss_basic_list_read readme.tacocat.txt +Q -cn "TacocaT Readme Documentation" | iki_read +Q -w -rr FLL FLL DNS DNS -W code '"' '"'
#
TacocaT Readme Documentation:
This program is similar to code:"netcat" or code:"nc" but is not intended to function as a replacement for these tools.
- The primary use for this is to test bold:"Featureless Linux Library" and bold:"Kevux Tools" network functionality.
+ The primary use for this is to test FLL:"Featureless Linux Library" and bold:"Kevux Tools" network functionality.
The bold:"tacocat" program has the following arguments\:
#define kt_tacocat_cache_size_peek_d (kt_tacocat_block_size_receive_d + 1)
#define kt_tacocat_interval_poll_d 1400 // 1.4 second.
- #define kt_tacocat_interval_poll_fast_d 50 // 0.05 second.
+ #define kt_tacocat_interval_poll_fast_d 5 // 0.005 second.
#define kt_tacocat_max_backlog_d 0x400
#define kt_tacocat_max_buffer_d 0x10000000 // 0x10^0x5 * 0x100 (Which is 256 Megabytes (0x10^0x5 where the base unit is 16 rather than 10 or 2 (maybe call this xytes? Megaxytes?)).
* 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 not processing within flag kt_tacocat_socket_flag_receive_control_e.
+ * Intended to be used for handling an error during the receive process while not processing within step kt_tacocat_socket_step_receive_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:
* A version of macro_kt_receive_process_handle_error_exit_1 that uses a void return statement.
*
* 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_receive_control_e.
+ * Intended to be used for handling an error during the receive process while processing within step kt_tacocat_socket_step_receive_control_e.
*
- * @todo document macro_kt_send_process_handle_error_exit_1.
+ * @todo document all macros.
*/
#ifndef _di_kt_tacocat_macros_d_
#define macro_setting_load_print_first() \
continue; \
}
- #define macro_kt_receive_process_handle_error_exit_1(main, method, network, status, name, flag, id_data) \
+ #define macro_kt_receive_process_handle_error_exit_1(main, method, network, status, name, step, 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, network, status, name); \
\
f_file_close_id(id_data); \
} \
\
- flag = 0; \
+ step = 0; \
\
return F_done_not; \
}
- #define macro_kt_receive_process_handle_error_exit_2(main, method, network, status, name, flag, id_data) \
+ #define macro_kt_receive_process_handle_error_exit_2(main, method, network, status, name, step, 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, network, status, name); \
\
f_file_close_id(id_data); \
} \
\
- flag = 0; \
+ step = 0; \
\
return; \
}
- #define macro_kt_receive_process_begin_handle_error_exit_1(main, method, network, status, name, flag) \
+ #define macro_kt_receive_process_begin_handle_error_exit_1(main, method, network, status, name, step) \
if (F_status_is_error(status)) { \
kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, network, status, name); \
\
- flag = 0; \
+ step = 0; \
\
return; \
}
- #define macro_kt_send_process_handle_error_exit_1(main, method, on, network, status, name, flag) \
+ #define macro_kt_send_process_handle_error_exit_1(main, method, on, network, status, name, step) \
if (F_status_is_error(status)) { \
kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), on, network, status, name); \
\
/**
* Types of packets.
*
- * kt_tacocat_print_flag_*_e:
+ * kt_tacocat_packet_type_*_e:
* - none: No type is set.
- * - done: The package concludes the connection (from the sender or receiver) or acknowledges the receipt of a packet (receiver).
+ * - abort: The packet is designates that the connection is to be aborted.
+ * - done: The package acknowledges the receipt of a packet.
* - file: The packet is a file.
* - next: The packet is a request for the next file.
* - resend: The packet is a request to resend the given part number.
*/
-#ifndef _di_kt_tacocat_print_flag_e_
+#ifndef _di_kt_tacocat_packet_type_e_
enum {
kt_tacocat_packet_type_none_e = 0x0,
- kt_tacocat_packet_type_done_e = 0x1,
- kt_tacocat_packet_type_file_e = 0x2,
- kt_tacocat_packet_type_next_e = 0x4,
- kt_tacocat_packet_type_resend_e = 0x8,
+ kt_tacocat_packet_type_abort_e = 0x1,
+ kt_tacocat_packet_type_done_e = 0x2,
+ kt_tacocat_packet_type_file_e = 0x4,
+ kt_tacocat_packet_type_next_e = 0x8,
+ kt_tacocat_packet_type_resend_e = 0x10,
}; // enum
-#endif // _di_kt_tacocat_print_flag_e_
+#endif // _di_kt_tacocat_packet_type_e_
/**
* Flags for fine-tuned print control.
#endif // _di_kt_tacocat_print_flag_e_
/**
- * Individual socket-specific flags for receiving.
+ * Socket related flags, such as designating handling of error packet.
+ *
+ * kt_tacocat_socket_flag_*_e:
+ * - none: No flags set.
+ * - abort: Abort connection.
+ * - done: Send packet confirming that everything is done.
+ * - listen: Listen for a response to a previously sent connection.
+ * - next: Request or Send next packet for existing connection.
+ * - resend: Send packet for requesting a re-send of the previous packet.
+ */
+#ifndef _di_kt_tacocat_socket_flag_e_
+ enum {
+ kt_tacocat_socket_flag_none_e = 0,
+ kt_tacocat_socket_flag_abort_e = 0x1,
+ kt_tacocat_socket_flag_done_e = 0x2,
+ kt_tacocat_socket_flag_listen_e = 0x4,
+ kt_tacocat_socket_flag_next_e = 0x8,
+ kt_tacocat_socket_flag_resend_e = 0x10,
+ }; // enum
+#endif // _di_kt_tacocat_socket_flag_e_
+
+/**
+ * Individual socket-specific steps for receiving.
*
- * kt_tacocat_socket_flag_receive_*_e:
+ * kt_tacocat_socket_step_receive_*_e:
* - none: No flags set.
* - control: Reading and processing the Control block and Size block.
* - packet: Reading and processing the rest of the Packet block (the Header and Payload sections).
* - write: Save the loaded Payload block to the file (write to the file).
* - done: Done processing file.
*/
-#ifndef _di_kt_tacocat_socket_flag_receive_e_
+#ifndef _di_kt_tacocat_socket_step_receive_e_
enum {
- kt_tacocat_socket_flag_receive_none_e = 0x0,
- kt_tacocat_socket_flag_receive_control_e = 0x1,
- kt_tacocat_socket_flag_receive_packet_e = 0x2,
- kt_tacocat_socket_flag_receive_find_e = 0x4,
- kt_tacocat_socket_flag_receive_extract_e = 0x8,
- kt_tacocat_socket_flag_receive_check_e = 0x10,
- kt_tacocat_socket_flag_receive_write_e = 0x20,
- kt_tacocat_socket_flag_receive_done_e = 0x40,
+ kt_tacocat_socket_step_receive_none_e = 0,
+ kt_tacocat_socket_step_receive_control_e,
+ kt_tacocat_socket_step_receive_packet_e,
+ kt_tacocat_socket_step_receive_find_e,
+ kt_tacocat_socket_step_receive_extract_e,
+ kt_tacocat_socket_step_receive_check_e,
+ kt_tacocat_socket_step_receive_write_e,
+ kt_tacocat_socket_step_receive_done_e,
}; // enum
-#endif // _di_kt_tacocat_socket_flag_receive_e_
+#endif // _di_kt_tacocat_socket_step_receive_e_
/**
- * Individual socket-specific flags for receiving.
+ * Individual socket-specific steps for receiving.
*
- * kt_tacocat_socket_flag_send_*_e:
+ * kt_tacocat_socket_step_send_*_e:
* - none: No flags set.
* - size: Determine the file size.
* - header: Build and buffer the header.
* - packet: Send the entire packet.
* - done: The entire Packet is sent.
*/
-#ifndef _di_kt_tacocat_socket_flag_send_e_
+#ifndef _di_kt_tacocat_socket_step_send_e_
enum {
- kt_tacocat_socket_flag_send_none_e = 0x0,
- kt_tacocat_socket_flag_send_size_e = 0x1,
- kt_tacocat_socket_flag_send_header_e = 0x2,
- kt_tacocat_socket_flag_send_build_e = 0x4,
- kt_tacocat_socket_flag_send_file_e = 0x8,
- kt_tacocat_socket_flag_send_check_e = 0x10,
- kt_tacocat_socket_flag_send_encode_e = 0x20,
- kt_tacocat_socket_flag_send_packet_e = 0x40,
- kt_tacocat_socket_flag_send_done_e = 0x80,
+ kt_tacocat_socket_step_send_none_e = 0,
+ kt_tacocat_socket_step_send_size_e,
+ kt_tacocat_socket_step_send_header_e,
+ kt_tacocat_socket_step_send_build_e,
+ kt_tacocat_socket_step_send_file_e,
+ kt_tacocat_socket_step_send_check_e,
+ kt_tacocat_socket_step_send_encode_e,
+ kt_tacocat_socket_step_send_packet_e,
+ kt_tacocat_socket_step_send_done_e,
}; // enum
-#endif // _di_kt_tacocat_socket_flag_send_e_
+#endif // _di_kt_tacocat_socket_step_send_e_
#ifdef __cplusplus
} // extern "C"
"fll_fss_payload_read",
"fll_program_parameter_process_context",
"fll_program_parameter_process_verbosity",
+ "kt_tacocat_process_abstruse_initialize",
"kt_tacocat_process_socket_set_error_has",
"kt_tacocat_setting_load_address_port_extract",
+ "kt_tacocat_setting_load_send_receive_allocate",
};
#endif // _di_kt_tacocat_f_a_
kt_tacocat_f_fll_fss_payload_read_e,
kt_tacocat_f_fll_program_parameter_process_context_e,
kt_tacocat_f_fll_program_parameter_process_verbosity_e,
+ kt_tacocat_f_kt_tacocat_process_abstruse_initialize_e,
kt_tacocat_f_kt_tacocat_process_socket_set_error_has_e,
kt_tacocat_f_kt_tacocat_setting_load_address_port_extract_e,
kt_tacocat_f_kt_tacocat_setting_load_send_receive_allocate_e,
#endif // _di_utf8_program_help_parameters_s_
#ifndef _di_kt_tacocat_s_
+ const f_string_static_t kt_tacocat_abort_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_abort_s, 0, KT_TACOCAT_abort_s_length);
const f_string_static_t kt_tacocat_classic_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_classic_s, 0, KT_TACOCAT_classic_s_length);
const f_string_static_t kt_tacocat_digit_negative_one_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_digit_negative_one_s, 0, KT_TACOCAT_digit_negative_one_s_length);
const f_string_static_t kt_tacocat_done_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_done_s, 0, KT_TACOCAT_done_s_length);
* kt_tacocat_*_s: Arbitrary strings.
*/
#ifndef _di_kt_tacocat_s_
+ #define KT_TACOCAT_abort_s "abort"
#define KT_TACOCAT_classic_s "classic"
#define KT_TACOCAT_digit_negative_one_s "-1"
#define KT_TACOCAT_done_s "done"
#define KT_TACOCAT_tacocat_s "tacocat"
#define KT_TACOCAT_two_s "two"
+ #define KT_TACOCAT_abort_s_length 5
#define KT_TACOCAT_classic_s_length 7
#define KT_TACOCAT_digit_negative_one_s_length 2
#define KT_TACOCAT_done_s_length 4
#define KT_TACOCAT_tacocat_s_length 7
#define KT_TACOCAT_two_s_length 3
+ extern const f_string_static_t kt_tacocat_abort_s;
extern const f_string_static_t kt_tacocat_classic_s;
extern const f_string_static_t kt_tacocat_digit_negative_one_s;
extern const f_string_static_t kt_tacocat_done_s;
f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &array[i].contents_delimits_header.array, &array[i].contents_delimits_header.used, &array[i].contents_delimits_header.size);
}
+ if (array[i].parts.size) {
+ f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &array[i].parts.array, &array[i].parts.used, &array[i].parts.size);
+ }
+
if (array[i].contents_delimits_signature.size) {
f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &array[i].contents_delimits_signature.array, &array[i].contents_delimits_signature.used, &array[i].contents_delimits_signature.size);
}
* size_total: The size in bytes tht represent the entire size to be processed (size_done should eventually equal this).
*
* flag: A set of flags.
+ * step: The current step the socket set is operating under.
* retry: The current number of retries performed.
* file: The file structure.
* socket: Socket structure.
* contents_delimits: An array of FSS Content delimits.
* contents_delimits_header: An array of FSS Content delimits, for the Header section.
* contents_delimits_signature: An array of FSS Content delimits, for the Signature section.
+ * parts: An array of numbers where each index represents a part number.
* objects_quoted_header: An array of FSS Objects quoted flags, for the Header section.
* objects_quoted_signature: An array of FSS Objects quoted flags, for the Header section.
* contents_quoted_header: An array of FSS Content quoted flags, for the Header section.
size_t size_total;
uint16_t flag;
+ uint16_t step;
uint16_t retry;
f_file_t file;
f_socket_t socket;
f_number_unsigneds_t contents_delimits;
f_number_unsigneds_t contents_delimits_header;
f_number_unsigneds_t contents_delimits_signature;
+ f_number_unsigneds_t parts;
f_uint8s_t objects_quoted_header;
f_uint8s_t objects_quoted_signature;
f_uint8ss_t contents_quoted_header;
f_number_unsigneds_t_initialize, \
f_number_unsigneds_t_initialize, \
f_number_unsigneds_t_initialize, \
+ f_number_unsigneds_t_initialize, \
f_uint8s_t_initialize, \
f_uint8s_t_initialize, \
f_uint8ss_t_initialize, \
f_number_unsigneds_t_initialize, \
f_number_unsigneds_t_initialize, \
f_number_unsigneds_t_initialize, \
+ f_number_unsigneds_t_initialize, \
f_uint8s_t_initialize, \
f_uint8s_t_initialize, \
f_uint8ss_t_initialize, \
f_number_unsigneds_t_initialize, \
f_number_unsigneds_t_initialize, \
f_number_unsigneds_t_initialize, \
+ f_number_unsigneds_t_initialize, \
f_uint8s_t_initialize, \
f_uint8s_t_initialize, \
f_uint8ss_t_initialize, \
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, set->name, print->set->notable);
fl_print_format("%['", print->to, print->set->error);
- if (set->flag & kt_tacocat_socket_flag_receive_find_e) {
+ if (set->flag == kt_tacocat_socket_step_receive_find_e) {
fl_print_format(" while trying to process the Packet headers", print->to);
}
}
#endif // _di_kt_tacocat_process_main_
+#ifndef _di_kt_tacocat_process_abstruse_initialize_
+ void kt_tacocat_process_abstruse_initialize(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ set->status = f_memory_array_increase_by(kt_tacocat_packet_headers_d, sizeof(f_abstruse_map_t), (void **) &set->abstruses.array, &set->abstruses.used, &set->abstruses.size);
+ if (F_status_is_error(set->status)) return;
+
+ // Index 0 is the status.
+ set->abstruses.array[0].key = f_fss_payload_object_status_s;
+ set->abstruses.array[0].value.type = f_abstruse_dynamic_e;
+ set->abstruses.array[0].value.is.a_dynamic = f_status_okay_s;
+
+ // Index 1 is the type.
+ set->abstruses.array[1].key = f_fss_payload_object_type_s;
+ set->abstruses.array[1].value.type = f_abstruse_dynamic_e;
+ set->abstruses.array[1].value.is.a_dynamic = f_file_type_name_file_s;
+
+ // Index 2 is the length.
+ set->abstruses.array[2].key = f_fss_payload_object_length_s;
+ set->abstruses.array[2].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[2].value.is.a_unsigned = 0;
+
+ // Index 3 is the part.
+ set->abstruses.array[3].key = f_fss_payload_object_part_s;
+ set->abstruses.array[3].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[3].value.is.a_unsigned = 0;
+
+ // Index 4 is the total number of packets (based on block size).
+ set->abstruses.array[4].key = f_fss_payload_object_total_s;
+ set->abstruses.array[4].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[4].value.is.a_unsigned = 0;
+
+ // Index 5 is the name.
+ set->abstruses.array[5].key = f_fss_payload_object_name_s;
+ set->abstruses.array[5].value.type = f_abstruse_dynamic_e;
+ set->abstruses.array[5].value.is.a_dynamic = set->name;
+
+ // Index 6 is the salt.
+ set->abstruses.array[6].key = kt_tacocat_salt_s;
+ set->abstruses.array[6].value.type = f_abstruse_unsigned_e;
+
+ {
+ long salt = 0;
+
+ f_random_get(&salt);
+
+ set->abstruses.array[6].value.is.a_unsigned = (f_number_unsigned_t) salt;
+ }
+
+ set->abstruses.used = 7;
+ }
+#endif // _di_kt_tacocat_process_abstruse_initialize_
+
#ifndef _di_kt_tacocat_process_socket_set_error_has_
f_status_t kt_tacocat_process_socket_set_error_has(kt_tacocat_main_t * const main, const f_string_static_t parameter, const kt_tacocat_socket_sets_t set, f_status_t * const status) {
#endif // _di_kt_tacocat_process_main_
/**
+ * Initialize the abstruse for the send or receive process.
+ *
+ * This initializes the abstruse to the standard packet abstruse structure.
+ *
+ * Standard abstruse packet index positions:
+ * 0: status.
+ * 1: type.
+ * 2: length.
+ * 3: part.
+ * 4: total.
+ * 5: name.
+ * 6: salt.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This does not alter main.setting.state.status, except on interrupt signal.
+ * @param set
+ * The socket set to process.
+ * Must not be NULL.
+ *
+ * This alters set.status:
+ * Success from: f_memory_array_increase_by().
+ *
+ * Errors (with error bit) from: f_memory_array_increase_by().
+ *
+ * @see f_memory_array_increase_by()
+ */
+#ifndef _di_kt_tacocat_process_abstruse_initialize_
+ extern void kt_tacocat_process_abstruse_initialize(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_process_abstruse_initialize_
+
+/**
* Disconnect the socket set and close open file.
*
* @param main
if (F_status_is_error_not(main->setting.status_receive) && main->setting.receive.used) {
do {
+ // @todo this would probably be better when active_receive > 0 to add a nano timestamp check and if time elapsed is smaller than a given number then do not poll.
main->setting.status_receive = f_file_poll(main->setting.receive_polls, main->setting.active_receive ? main->setting.interval_fast : main->setting.interval);
if (main->program.signal_received) {
return 0;
}
- // @todo or check if there is any lingering in-progress process not waiting on receive.
- // @todo when there is a lingering iin-progress process, change the poll timeout to a shorter period to process the lingering process more.
// Skip if status from poll is an error or is F_time_out.
- if (main->setting.status_receive == F_okay) {
+ if (main->setting.active_receive >> main->setting.status_receive == F_okay) {
for (i = 0; i < main->setting.receive_polls.used; ++i) {
if (main->setting.receive_polls.array[i].fd == -1) continue;
// Keep error bit but set state to done to designate that nothing else is to be done.
main->setting.receive.array[i].status = F_status_set_error(F_done);
- if (main->setting.receive.array[i].flag) {
- main->setting.receive.array[i].flag = 0;
+ if (main->setting.receive.array[i].step) {
+ main->setting.receive.array[i].step = 0;
if (main->setting.active_receive) {
--main->setting.active_receive;
kt_tacocat_print_error_on_max_retries_receive(&main->program.error, &main->setting.receive.array[i]);
}
- // @todo if flag is kt_tacocat_socket_flag_receive_control_e, check if error is either F_packet_too_small or F_packet_too_large. This is a non-retrying error.
+ // @todo if step is kt_tacocat_socket_step_receive_control_e, check if error is either F_packet_too_small or F_packet_too_large. This is a non-retrying error.
}
}
else {
// Keep error bit but set state to done to designate that nothing else is to be done. @todo review and confirm if this assignment with error bit set is needed anymore or should be changed.
main->setting.receive.array[i].status = F_status_set_error(F_done);
- if (main->setting.receive.array[i].flag) {
- main->setting.receive.array[i].flag = 0;
+ if (main->setting.receive.array[i].step) {
+ main->setting.receive.array[i].step = 0;
if (main->setting.active_receive) {
--main->setting.active_receive;
if (!main || !set) return F_status_set_error(F_parameter);
- // This is a new packet (kt_tacocat_socket_flag_receive_none_e).
- if (!(set->flag)) {
+ // This is a new packet (kt_tacocat_socket_step_receive_none_e).
+ if (!(set->step)) {
kt_tacocat_print_message_receive_operation_received(&main->program.message, *set);
set->abstruses.used = 0;
set->packet.size = 0;
set->packet.payload.start = 1;
set->packet.payload.stop = 0;
- set->flag = kt_tacocat_socket_flag_receive_control_e;
+ set->step = kt_tacocat_socket_step_receive_control_e;
+ set->flag = 0;
++main->setting.active_receive;
}
// Keep error bit but set state to done to designate that nothing else is to be done.
set->status = F_status_set_error(F_done);
- set->flag = 0;
+ set->step = 0;
if (main->setting.active_receive) {
--main->setting.active_receive;
}
// Load the header of the new packet.
- if (set->flag & kt_tacocat_socket_flag_receive_control_e) {
+ if (set->step == kt_tacocat_socket_step_receive_control_e) {
kt_tacocat_receive_process_control(main, set);
if (set->buffer.used < kt_tacocat_packet_peek_d || F_status_is_error(set->status)) {
set->retry = 0;
set->buffer.used = 0;
- set->flag = kt_tacocat_socket_flag_receive_packet_e;
+ set->step = kt_tacocat_socket_step_receive_packet_e;
}
- if (set->flag & kt_tacocat_socket_flag_receive_packet_e) {
+ if (set->step == kt_tacocat_socket_step_receive_packet_e) {
size_t length_read = 0;
set->status = f_socket_read_stream(&set->socket, 0, (void *) (set->buffer.string + set->buffer.used), &length_read);
}
set->range.stop = set->buffer.used - 1;
- set->flag = kt_tacocat_socket_flag_receive_find_e;
+ set->step = kt_tacocat_socket_step_receive_find_e;
}
else {
++set->retry;
}
}
- if (set->flag & kt_tacocat_socket_flag_receive_find_e) {
+ if (set->step == kt_tacocat_socket_step_receive_find_e) {
set->state.status = F_none;
fll_fss_payload_read(set->buffer, &set->range, &set->objects, &set->contents, &set->objects_delimits, &set->contents_delimits, &set->comments, &set->state);
if (set->buffer.used == set->packet.size) {
// The packet is fully loaded and there is no "payload" section.
- set->flag = kt_tacocat_socket_flag_receive_extract_e;
+ set->step = kt_tacocat_socket_step_receive_extract_e;
}
else {
} // while
// No packet is found and is not yet finished loading the data.
- set->flag = kt_tacocat_socket_flag_receive_packet_e;
+ set->step = kt_tacocat_socket_step_receive_packet_e;
}
break;
} // while
if (set->buffer.used != set->packet.size) {
- set->flag = kt_tacocat_socket_flag_receive_packet_e;
+ set->step = kt_tacocat_socket_step_receive_packet_e;
}
++set->retry;
case F_data_not_eos:
case F_data_not_stop:
case F_fss_found_object_content_not:
- set->flag = kt_tacocat_socket_flag_receive_extract_e;
+ set->step = kt_tacocat_socket_step_receive_extract_e;
break;
}
}
- if (set->flag & kt_tacocat_socket_flag_receive_extract_e) {
+ if (set->step == kt_tacocat_socket_step_receive_extract_e) {
kt_tacocat_receive_process_extract(main, set);
if (F_status_is_error(set->status)) return F_data_not;
- set->flag = kt_tacocat_socket_flag_receive_write_e;
+ set->step = kt_tacocat_socket_step_receive_write_e;
}
- if (set->flag & kt_tacocat_socket_flag_receive_check_e) {
+ if (set->step == kt_tacocat_socket_step_receive_check_e) {
// @todo
- set->flag = kt_tacocat_socket_flag_receive_write_e;
+ set->step = kt_tacocat_socket_step_receive_write_e;
}
- if (set->flag & kt_tacocat_socket_flag_receive_write_e) {
+ if (set->step == kt_tacocat_socket_step_receive_write_e) {
set->status = f_file_open(set->name, F_file_mode_all_rw_d, &set->file);
if (F_status_is_error(set->status)) {
f_file_close(&set->file);
set->buffer.used = 0;
- set->flag = kt_tacocat_socket_flag_receive_done_e;
+ set->step = kt_tacocat_socket_step_receive_done_e;
}
// Done processing the Packet.
- if (set->flag & kt_tacocat_socket_flag_receive_done_e) {
+ if (set->step == kt_tacocat_socket_step_receive_done_e) {
kt_tacocat_print_message_receive_operation_complete(&main->program.message, *set);
f_file_close(&set->file);
- set->flag = 0;
+ set->step = 0;
set->status = F_okay;
if (main->setting.active_receive) {
set->status = f_socket_accept(&set->socket);
// 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, set->network, set->status, set->name, set->flag);
+ macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_accept, set->network, set->status, set->name, set->step);
set->status = f_memory_array_increase_by(kt_tacocat_packet_peek_d + 1, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
- macro_kt_receive_process_begin_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->name, set->flag);
+ macro_kt_receive_process_begin_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->name, set->step);
set->socket.size_read = kt_tacocat_packet_peek_d;
set->socket.size_read = size_read;
- macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_read_stream, set->network, set->status, set->name, set->flag);
+ macro_kt_receive_process_begin_handle_error_exit_1(main, f_socket_read_stream, set->network, set->status, set->name, set->step);
set->buffer.used += length_read;
// Connection is closed when length is 0.
kt_tacocat_print_warning_on_client_closed(&main->program.warning, kt_tacocat_receive_s, set->network);
- set->flag = 0;
+ set->step = 0;
set->status = F_status_set_error(F_packet_too_small);
return;
}
set->status = f_fss_simple_packet_decode_range(set->buffer, &set->packet);
- macro_kt_receive_process_begin_handle_error_exit_1(main, f_fss_simple_packet_decode_range, set->network, set->status, set->name, set->flag);
+ macro_kt_receive_process_begin_handle_error_exit_1(main, f_fss_simple_packet_decode_range, set->network, set->status, set->name, set->step);
if (set->status == F_packet_too_small || set->packet.size < kt_tacocat_packet_minimum_d || set->packet.size > main->setting.max_buffer) {
set->buffer.used = 0;
}
}
- set->flag = 0;
+ set->step = 0;
if (set->status == F_packet_too_small || set->packet.size < kt_tacocat_packet_minimum_d) {
set->status = F_status_set_error(F_packet_too_small);
if (!main || !set) return;
- set->status = f_memory_array_increase_by(kt_tacocat_packet_headers_d, sizeof(f_abstruse_map_t), (void **) &set->abstruses.array, &set->abstruses.used, &set->abstruses.size);
+ kt_tacocat_process_abstruse_initialize(main, set);
if (F_status_is_error(set->status)) {
- macro_kt_receive_process_handle_error_exit_2(main, f_memory_array_increase_by, set->network, set->status, set->name, set->flag, &set->socket.id_data);
+ macro_kt_receive_process_handle_error_exit_2(main, kt_tacocat_process_abstruse_initialize, set->network, set->status, set->name, set->step, &set->socket.id_data);
}
// 0x1 = did not find payload, 0x2 = did not find header.
* Errors (with error bit) from: f_socket_read_stream().
* Errors (with error bit) from: kt_tacocat_receive_process_control().
*
+ * @return
+ * F_done on success and done processing.
+ * F_done_not on success but not done processing.
+ *
+ * F_parameter (with error bit) on invalid parameter.
+ *
* @see f_file_open()
* @see f_file_write()
* @see f_memory_array_increase_by()
if (!main || !set) return F_status_set_error(F_parameter);
- if (!set->flag) {
+ if (!set->step) {
set->abstruses.used = 0;
set->buffer.used = 0;
set->cache.used = 0;
set->packet.control = 0;
set->packet.size = 0;
set->status = F_none;
+ set->flag = 0;
// For writes, the id_data is the same as the id.
set->socket.id_data = set->socket.id;
}
if (F_status_is_error_not(set->status)) {
- set->status = f_memory_array_increase_by(kt_tacocat_packet_headers_d, sizeof(f_abstruse_map_t), (void **) &set->abstruses.array, &set->abstruses.used, &set->abstruses.size);
+ kt_tacocat_process_abstruse_initialize(main, set);
}
if (F_status_is_error(set->status)) {
- macro_kt_send_process_handle_error_exit_1(main, f_memory_array_increase_by, kt_tacocat_send_s, set->network, set->status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, f_memory_array_increase_by, kt_tacocat_send_s, set->network, set->status, set->name, set->step);
}
- // Index 0 is the status.
- set->abstruses.array[0].key = f_fss_payload_object_status_s;
- set->abstruses.array[0].value.type = f_abstruse_dynamic_e;
- set->abstruses.array[0].value.is.a_dynamic = f_status_okay_s;
-
- // Index 1 is the type.
- set->abstruses.array[1].key = f_fss_payload_object_type_s;
- set->abstruses.array[1].value.type = f_abstruse_dynamic_e;
- set->abstruses.array[1].value.is.a_dynamic = f_file_type_name_file_s;
-
- // Index 2 is the length.
- set->abstruses.array[2].key = f_fss_payload_object_length_s;
- set->abstruses.array[2].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[2].value.is.a_unsigned = 0;
-
- // Index 3 is the part.
- set->abstruses.array[3].key = f_fss_payload_object_part_s;
- set->abstruses.array[3].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[3].value.is.a_unsigned = 0;
-
- // Index 4 is the total number of packets (based on block size).
- set->abstruses.array[4].key = f_fss_payload_object_total_s;
- set->abstruses.array[4].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[4].value.is.a_unsigned = 0;
-
- // Index 5 is the name.
- set->abstruses.array[5].key = f_fss_payload_object_name_s;
- set->abstruses.array[5].value.type = f_abstruse_dynamic_e;
- set->abstruses.array[5].value.is.a_dynamic = set->name;
-
- // Index 6 is the salt.
- set->abstruses.array[6].key = kt_tacocat_salt_s;
- set->abstruses.array[6].value.type = f_abstruse_unsigned_e;
-
- {
- long salt = 0;
-
- f_random_get(&salt);
-
- set->abstruses.array[6].value.is.a_unsigned = (f_number_unsigned_t) salt;
- }
-
- set->abstruses.used = 7;
-
- set->flag = kt_tacocat_socket_flag_send_size_e;
+ set->step = kt_tacocat_socket_step_send_size_e;
}
if (set->retry >= kt_tacocat_startup_retry_max_d) {
f_file_close(&set->file);
f_socket_disconnect(&set->socket, f_socket_close_fast_e);
- set->flag = 0;
+ set->step = 0;
set->socket.id_data = -1;
// Keep error bit but set state to done to designate that nothing else is to be done.
}
// @todo when total > 1, then this needs to build each part, incrementing part each time (every time this needs to be done, the entire header structure needs to be rebuilt until part == total - 1) (the receive code needs to also be sure to handle multiple parts).
- if (set->flag & kt_tacocat_socket_flag_send_size_e) {
+ if (set->step == kt_tacocat_socket_step_send_size_e) {
if (set->file.id == -1) {
set->status = f_file_open(set->name, F_file_mode_all_r_d, &set->file);
set->abstruses.array[4].value.is.a_unsigned = 1;
}
- set->flag = kt_tacocat_socket_flag_send_build_e;
+ set->status = f_memory_array_increase_by(set->abstruses.array[4].value.is.a_unsigned, sizeof(f_number_unsigned_t), (void **) &.array, &.used, &.size);
+
+ if (F_status_is_error(set->status)) {
+ // @todo out of memory, send abort packet with F_memory as a status.
+ // @todo pre-build an out of memory packet as a static string, with reserved space for the salt.
+ // @todo packets like this need to be sent
+ f_file_close(&set->file);
+ f_socket_disconnect(&set->socket, f_socket_close_fast_e);
+
+ set->step = 0;
+ set->socket.id_data = -1;
+
+ // Keep error bit but set state to done to designate that nothing else is to be done.
+ set->status = F_status_set_error(F_done);
+
+ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_increase_by), kt_tacocat_send_size_s, set->network, set->status, set->name);
+
+ return;
+ }
+
+ set->step = kt_tacocat_socket_step_send_build_e;
}
- if (set->flag & kt_tacocat_socket_flag_send_build_e) {
+ if (set->step == kt_tacocat_socket_step_send_build_e) {
f_state_t state_local = main->setting.state;
state_local.data = &set->write_state;
fl_fss_payload_header_map(set->abstruses, &set->headers, &state_local);
- macro_kt_send_process_handle_error_exit_1(main, fl_fss_payload_header_map, kt_tacocat_send_build_s, set->network, state_local.status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, fl_fss_payload_header_map, kt_tacocat_send_build_s, set->network, state_local.status, set->name, set->step);
- set->flag = kt_tacocat_socket_flag_send_header_e;
+ set->step = kt_tacocat_socket_step_send_header_e;
}
- if (set->flag & kt_tacocat_socket_flag_send_header_e) {
+ if (set->step == kt_tacocat_socket_step_send_header_e) {
// @todo this needs to check the current status, accodingly (for when multiple blocks are being sent).
// Reserve the FSS Packet header, which will be calculated just before sending.
} // for
}
- macro_kt_send_process_handle_error_exit_1(main, f_string_dynamic_append_nulless, kt_tacocat_send_combine_s, set->network, set->status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, f_string_dynamic_append_nulless, kt_tacocat_send_combine_s, set->network, set->status, set->name, set->step);
- set->flag = kt_tacocat_socket_flag_send_file_e;
+ set->step = kt_tacocat_socket_step_send_file_e;
}
- if (set->flag & kt_tacocat_socket_flag_send_file_e) {
+ if (set->step == kt_tacocat_socket_step_send_file_e) {
const f_number_unsigned_t size_header = set->buffer.used;
set->status = f_string_dynamic_append(f_fss_payload_object_payload_s, &set->buffer);
set->status = f_string_dynamic_append(f_fss_payload_object_end_s, &set->buffer);
}
- macro_kt_send_process_handle_error_exit_1(main, f_string_dynamic_append, kt_tacocat_send_file_s, set->network, set->status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, f_string_dynamic_append, kt_tacocat_send_file_s, set->network, set->status, set->name, set->step);
// Always reset the seek position in case a retry happened after the file block is read.
{
off_t seeked = 0;
set->status = f_file_seek(set->file, SEEK_SET, set->size_done, &seeked);
- macro_kt_send_process_handle_error_exit_1(main, f_file_seek, kt_tacocat_send_file_s, set->network, set->status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, f_file_seek, kt_tacocat_send_file_s, set->network, set->status, set->name, set->step);
}
set->status = f_file_read_block(set->file, &set->buffer);
- macro_kt_send_process_handle_error_exit_1(main, f_file_read_block, kt_tacocat_send_file_s, set->network, set->status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, f_file_read_block, kt_tacocat_send_file_s, set->network, set->status, set->name, set->step);
set->status = f_string_dynamic_terminate_after(&set->buffer);
- macro_kt_send_process_handle_error_exit_1(main, f_string_dynamic_terminate_after, kt_tacocat_send_combine_s, set->network, set->status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, f_string_dynamic_terminate_after, kt_tacocat_send_combine_s, set->network, set->status, set->name, set->step);
set->retry = 0;
- set->flag = kt_tacocat_socket_flag_send_check_e;
+ set->step = kt_tacocat_socket_step_send_check_e;
}
- if (set->flag & kt_tacocat_socket_flag_send_check_e) {
+ if (set->step == kt_tacocat_socket_step_send_check_e) {
// @todo this needs to check if the size read has changed and then re-build the header (swap the buffer read block into the cache then rebuild the header with th new size).
//if (set->abstruses.array[2].value.is.a_unsigned < set->file.size_read) {
//}
- set->flag = kt_tacocat_socket_flag_send_encode_e;
+ set->step = kt_tacocat_socket_step_send_encode_e;
}
- if (set->flag & kt_tacocat_socket_flag_send_encode_e) {
+ if (set->step == kt_tacocat_socket_step_send_encode_e) {
const f_number_unsigned_t original = set->buffer.used;
set->buffer.used = 0;
set->buffer.used = original;
- macro_kt_send_process_handle_error_exit_1(main, f_fss_simple_packet_encode, kt_tacocat_send_payload_s, set->network, set->status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, f_fss_simple_packet_encode, kt_tacocat_send_payload_s, set->network, set->status, set->name, set->step);
- set->flag = kt_tacocat_socket_flag_send_packet_e;
+ set->step = kt_tacocat_socket_step_send_packet_e;
}
- if (set->flag & kt_tacocat_socket_flag_send_packet_e) {
+ if (set->step == kt_tacocat_socket_step_send_packet_e) {
size_t written = 0;
{
set->socket.size_write = original;
- macro_kt_send_process_handle_error_exit_1(main, f_socket_write_stream, kt_tacocat_send_payload_s, set->network, set->status, set->name, set->flag);
+ macro_kt_send_process_handle_error_exit_1(main, f_socket_write_stream, kt_tacocat_send_payload_s, set->network, set->status, set->name, set->step);
}
// @todo handle case when written < set->buffer.used, of which each pass. The entire buffer must be sent. May need another variable for say, set->size_process.
// When the buffer is smaller than the read block size, then the entire file should be completely sent.
if (set->size_done >= set->buffer.used) {
- set->flag = kt_tacocat_socket_flag_send_done_e;
+ set->step = kt_tacocat_socket_step_send_done_e;
}
else {
set->status = F_okay;
- set->flag = kt_tacocat_socket_flag_send_header_e;
+ set->step = kt_tacocat_socket_step_send_header_e;
return F_done_not;
}
}
- if (set->flag & kt_tacocat_socket_flag_send_done_e) {
+ if (set->step == kt_tacocat_socket_step_send_done_e) {
set->status = f_file_close(&set->file);
if (F_status_is_error(set->status)) {
kt_tacocat_print_warning_on_file(&main->program.warning, macro_kt_tacocat_f(f_socket_disconnect), kt_tacocat_send_done_s, set->network, set->status, set->name, f_file_operation_close_s);
}
- set->flag = 0;
+ set->step = 0;
set->socket.id_data = -1;
set->status = F_okay;
* F_payload_too_large (with error bit) on total payload size is too large.
* F_too_large (with error bit) on file too large.
*
+ * @return
+ * F_done on success and done processing.
+ * F_done_not on success but not done processing.
+ *
+ * F_parameter (with error bit) on invalid parameter.
+ *
* @see f_socket_read_stream()
*/
#ifndef _di_kt_tacocat_send_process_