This adds a lot more files but cleans up the code quite a bit.
The `kt_tacocat_send_process()` function is now easier to read and follow.
I anticipate doing similar things to other parts of TacocaT.
build_sources_program fll/level_2/print.c
build_sources_program fll/level_2/program.c fll/level_2/program/common.c fll/level_2/program/print.c fll/level_2/program/string.c fll/level_2/private-program.c
-build_sources_program program/kevux/tools/tacocat/main/common.c program/kevux/tools/tacocat/main/common/define.c program/kevux/tools/tacocat/main/common/enumeration.c program/kevux/tools/tacocat/main/common/string.c program/kevux/tools/tacocat/main/common/type.c program/kevux/tools/tacocat/main/print/error.c program/kevux/tools/tacocat/main/print/message.c program/kevux/tools/tacocat/main/print/verbose.c program/kevux/tools/tacocat/main/print/warning.c program/kevux/tools/tacocat/main/packet.c program/kevux/tools/tacocat/main/process.c program/kevux/tools/tacocat/main/receive.c program/kevux/tools/tacocat/main/send.c program/kevux/tools/tacocat/main/signal.c program/kevux/tools/tacocat/main/tacocat.c program/kevux/tools/tacocat/main/thread.c
-
+build_sources_program program/kevux/tools/tacocat/main/common.c program/kevux/tools/tacocat/main/common/define.c program/kevux/tools/tacocat/main/common/enumeration.c program/kevux/tools/tacocat/main/common/string.c program/kevux/tools/tacocat/main/common/type.c
+build_sources_program program/kevux/tools/tacocat/main/print/error.c program/kevux/tools/tacocat/main/print/message.c program/kevux/tools/tacocat/main/print/verbose.c program/kevux/tools/tacocat/main/print/warning.c
+build_sources_program program/kevux/tools/tacocat/main/packet.c program/kevux/tools/tacocat/main/process.c program/kevux/tools/tacocat/main/receive.c program/kevux/tools/tacocat/main/send.c program/kevux/tools/tacocat/main/signal.c program/kevux/tools/tacocat/main/tacocat.c program/kevux/tools/tacocat/main/thread.c
+build_sources_program program/kevux/tools/tacocat/main/send/step/build.c program/kevux/tools/tacocat/main/send/step/check.c program/kevux/tools/tacocat/main/send/step/done.c program/kevux/tools/tacocat/main/send/step/encode.c program/kevux/tools/tacocat/main/send/step/file.c program/kevux/tools/tacocat/main/send/step/header.c program/kevux/tools/tacocat/main/send/step/packet.c program/kevux/tools/tacocat/main/send/step/size.c program/kevux/tools/tacocat/main/send/step/wait.c
build_sources_program program/kevux/tools/tacocat/tacocat/config.c program/kevux/tools/tacocat/tacocat/tacocat.c program/kevux/tools/tacocat/tacocat/main.c program/kevux/tools/tacocat/tacocat/string.c
build_sources_documentation man
build_libraries_static-level -l:libfll_2.a -l:libfll_1.a -l:libfll_0.a
build_libraries_static-monolithic -l:libfll.a
-build_sources_library common.c common/define.c common/enumeration.c common/string.c common/type.c print/error.c print/message.c print/verbose.c print/warning.c packet.c process.c receive.c send.c signal.c tacocat.c thread.c
-
-build_sources_headers common.h common/define.h common/enumeration.h common/string.h common/type.h print/error.h print/message.h print/verbose.h print/warning.h packet.h process.h receive.h send.h signal.h tacocat.h thread.h
+build_sources_library common.c common/define.c common/enumeration.c common/string.c common/type.c
+build_sources_library print/error.c print/message.c print/verbose.c print/warning.c
+build_sources_library packet.c process.c receive.c send.c signal.c tacocat.c thread.c
+build_sources_library send/step/build.c send/step/check.c send/step/done.c send/step/encode.c send/step/file.c send/step/header.c send/step/packet.c send/step/size.c send/step/wait.c
+
+build_sources_headers common.h common/define.h common/enumeration.h common/string.h common/type.h
+build_sources_headers print/error.h print/message.h print/verbose.h print/warning.h
+build_sources_headers packet.h process.h receive.h send.h signal.h tacocat.h thread.h
+build_sources_headers send/step/build.h send/step/check.h send/step/done.h send/step/encode.h send/step/file.h send/step/header.h send/step/packet.h send/step/size.h send/step/wait.h
build_sources_documentation man
*
* These macros are intended to simplify repetitive parts of the code to improve readability.
*
- * macro_kt_tacocat_handle_send_process_error_exit_1:
- * Similar to macro_kt_tacocat_handle_receive_process_error_exit_1() but calls kt_tacocat_print_error_on_packet_invalid().
- *
* macro_kt_tacocat_handle_load_send_receive_error_continue_1:
* For use in kt_tacocat_setting_load_send_receive().
* This is for the basic error that calls kt_tacocat_print_error() when printing.
\
return; \
}
-
- #define macro_kt_tacocat_handle_send_process_error_exit_1(main, on, network, status, name, step) \
- if (F_status_is_error(status)) { \
- kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, on, network, status, name); \
- \
- return F_done_not; \
- }
#endif // _di_kt_tacocat_macro_d_
/**
const f_string_static_t kt_tacocat_send_combine_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_combine_s, 0, KT_TACOCAT_send_combine_s_length);
const f_string_static_t kt_tacocat_send_connect_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_connect_s, 0, KT_TACOCAT_send_connect_s_length);
const f_string_static_t kt_tacocat_send_done_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_done_s, 0, KT_TACOCAT_send_done_s_length);
+ const f_string_static_t kt_tacocat_send_encode_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_encode_s, 0, KT_TACOCAT_send_encode_s_length);
const f_string_static_t kt_tacocat_send_file_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_file_s, 0, KT_TACOCAT_send_file_s_length);
const f_string_static_t kt_tacocat_send_header_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_header_s, 0, KT_TACOCAT_send_header_s_length);
- const f_string_static_t kt_tacocat_send_payload_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_payload_s, 0, KT_TACOCAT_send_payload_s_length);
+ const f_string_static_t kt_tacocat_send_packet_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_packet_s, 0, KT_TACOCAT_send_packet_s_length);
const f_string_static_t kt_tacocat_send_size_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_send_size_s, 0, KT_TACOCAT_send_size_s_length);
const f_string_static_t kt_tacocat_socket_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_socket_s, 0, KT_TACOCAT_socket_s_length);
const f_string_static_t kt_tacocat_tacocat_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_tacocat_s, 0, KT_TACOCAT_tacocat_s_length);
#define KT_TACOCAT_send_combine_s "send combine"
#define KT_TACOCAT_send_connect_s "send connect"
#define KT_TACOCAT_send_done_s "send done"
+ #define KT_TACOCAT_send_encode_s "send encode"
#define KT_TACOCAT_send_file_s "send file"
#define KT_TACOCAT_send_header_s "send header"
- #define KT_TACOCAT_send_payload_s "send payload"
+ #define KT_TACOCAT_send_packet_s "send packet"
#define KT_TACOCAT_send_size_s "send size"
#define KT_TACOCAT_socket_s "socket"
#define KT_TACOCAT_tacocat_s "tacocat"
#define KT_TACOCAT_send_combine_s_length 12
#define KT_TACOCAT_send_connect_s_length 12
#define KT_TACOCAT_send_done_s_length 9
+ #define KT_TACOCAT_send_encode_s_length 11
#define KT_TACOCAT_send_file_s_length 9
#define KT_TACOCAT_send_header_s_length 11
- #define KT_TACOCAT_send_payload_s_length 12
+ #define KT_TACOCAT_send_packet_s_length 11
#define KT_TACOCAT_send_size_s_length 9
#define KT_TACOCAT_socket_s_length 6
#define KT_TACOCAT_tacocat_s_length 7
extern const f_string_static_t kt_tacocat_send_combine_s;
extern const f_string_static_t kt_tacocat_send_connect_s;
extern const f_string_static_t kt_tacocat_send_done_s;
+ extern const f_string_static_t kt_tacocat_send_encode_s;
extern const f_string_static_t kt_tacocat_send_file_s;
extern const f_string_static_t kt_tacocat_send_header_s;
- extern const f_string_static_t kt_tacocat_send_payload_s;
+ extern const f_string_static_t kt_tacocat_send_packet_s;
extern const f_string_static_t kt_tacocat_send_size_s;
extern const f_string_static_t kt_tacocat_socket_s;
extern const f_string_static_t kt_tacocat_tacocat_s;
kt_tacocat_send_process_initialize(main, set);
if (F_status_is_error(set->status)) {
- macro_kt_tacocat_handle_send_process_error_exit_1(main, kt_tacocat_send_s, set->network, set->status, set->name, set->step);
+ kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name);
+
+ return F_done_not;
}
set->step = kt_tacocat_socket_step_send_size_e;
// @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->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);
-
- if (F_status_is_error(set->status)) {
- kt_tacocat_print_error_on_file_receive(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_open_s);
-
- return F_done_not;
- }
- }
-
- // Total is used here to explicitly pass a pointer of off_t rather than a pointer of size_t cast to an off_t.
- off_t total = 0;
-
- set->status = f_file_size_by_id(set->file, &total);
-
- if (F_status_is_error(set->status)) {
- kt_tacocat_print_error_on_file_receive(&main->program.error, F_status_debug_source_d, kt_tacocat_send_size_s, set->network, set->status, set->name, f_file_operation_open_s);
-
- return F_done_not;
- }
-
- if ((f_number_unsigned_t) total > F_number_t_size_unsigned_d) {
- set->status = F_status_set_error(F_too_large);
-
- kt_tacocat_print_error_on_file_too_large(&main->program.error, set->name, kt_tacocat_send_size_s, set->network, F_number_t_size_unsigned_d, set->abstruses.array[4].value.is.a_unsigned);
-
- return F_done_not;
- }
-
- set->abstruses.array[3].value.is.a_unsigned = 0;
- set->size_total = (f_number_unsigned_t) total;
-
- if (total) {
- if (set->size_total < set->file.size_read) {
- set->abstruses.array[2].value.is.a_unsigned = set->size_total;
- set->abstruses.array[4].value.is.a_unsigned = 1;
- }
- else {
- set->abstruses.array[2].value.is.a_unsigned = set->file.size_read;
- set->abstruses.array[4].value.is.a_unsigned = set->size_total / set->file.size_read;
-
- if (set->abstruses.array[4].value.is.a_unsigned % set->file.size_read) {
- ++set->abstruses.array[4].value.is.a_unsigned;
- }
- }
- }
- else {
- set->abstruses.array[2].value.is.a_unsigned = set->size_total;
- set->abstruses.array[4].value.is.a_unsigned = 1;
- }
-
- set->status = f_memory_array_increase_by(set->abstruses.array[4].value.is.a_unsigned, sizeof(f_number_unsigned_t), (void **) &set->parts.array, &set->parts.used, &set->parts.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, F_status_debug_source_d, kt_tacocat_send_size_s, set->network, set->status, set->name);
-
- return F_done_not;
- }
-
- set->step = kt_tacocat_socket_step_send_build_e;
+ kt_tacocat_send_step_size(main, set);
}
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);
-
- set->status = state_local.status;
-
- macro_kt_tacocat_handle_send_process_error_exit_1(main, kt_tacocat_send_build_s, set->network, set->status, set->name, set->step);
-
- set->write_state.cache->used = 0;
-
- set->status = f_random_array_shuffle(0, set->headers.used, sizeof(f_string_map_t), set->write_state.cache, (void *) set->headers.array);
-
- macro_kt_tacocat_handle_send_process_error_exit_1(main, kt_tacocat_send_build_s, set->network, set->status, set->name, set->step);
-
- set->step = kt_tacocat_socket_step_send_header_e;
+ kt_tacocat_send_step_build(main, set);
}
if (set->step == kt_tacocat_socket_step_send_header_e) {
- // @todo this needs to check the current status, accordingly (for when multiple blocks are being sent).
-
- // Reserve the FSS Packet header, which will be calculated just before sending.
- set->buffer.used = 5;
- memset(set->buffer.string, 0, 5);
-
- set->status = f_string_dynamic_append_nulless(f_fss_payload_comment_header_begin_s, &set->buffer);
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_string_dynamic_append_nulless(f_fss_payload_comment_header_s, &set->buffer);
- }
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_string_dynamic_append_nulless(f_fss_payload_comment_header_end_s, &set->buffer);
- }
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_string_dynamic_append_nulless(f_fss_payload_object_header_s, &set->buffer);
- }
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_string_dynamic_append_nulless(f_fss_payload_object_end_s, &set->buffer);
- }
-
- if (F_status_is_error_not(set->status)) {
- for (f_number_unsigned_t i = 0; i < set->headers.used; ++i) {
-
- set->status = f_string_dynamic_append_nulless(set->headers.array[i].key, &set->buffer);
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_string_dynamic_append_nulless(f_fss_extended_open_s, &set->buffer);
- }
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_string_dynamic_append_nulless(set->headers.array[i].value, &set->buffer);
- }
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_string_dynamic_append_nulless(f_fss_extended_close_s, &set->buffer);
- }
- else {
- break;
- }
- } // for
- }
-
- macro_kt_tacocat_handle_send_process_error_exit_1(main, kt_tacocat_send_combine_s, set->network, set->status, set->name, set->step);
-
- set->step = kt_tacocat_socket_step_send_file_e;
+ kt_tacocat_send_step_header(main, set);
}
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);
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_string_dynamic_append(f_fss_payload_object_end_s, &set->buffer);
- }
-
- macro_kt_tacocat_handle_send_process_error_exit_1(main, 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_tacocat_handle_send_process_error_exit_1(main, 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_tacocat_handle_send_process_error_exit_1(main, kt_tacocat_send_file_s, set->network, set->status, set->name, set->step);
-
- set->status = f_string_dynamic_terminate_after(&set->buffer);
- macro_kt_tacocat_handle_send_process_error_exit_1(main, kt_tacocat_send_combine_s, set->network, set->status, set->name, set->step);
-
- set->retry = 0;
- set->step = kt_tacocat_socket_step_send_check_e;
+ kt_tacocat_send_step_file(main, set);
}
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->step = kt_tacocat_socket_step_send_encode_e;
+ kt_tacocat_send_step_check(main, set);
}
if (set->step == kt_tacocat_socket_step_send_encode_e) {
- const f_number_unsigned_t original = set->buffer.used;
-
- set->buffer.used = 0;
-
- // @todo there will need to be checks for max-size and the payload size, shrinking the payload if the header + payload is too large.
- // @todo if the header file is so large that the payload is smaller than a reasonable minumum (say 32 bytes), then this is a problem and throw a too large/small error.
- set->status = f_fss_simple_packet_encode(F_fss_simple_packet_endian_d, original, &set->buffer);
-
- set->buffer.used = original;
-
- macro_kt_tacocat_handle_send_process_error_exit_1(main, kt_tacocat_send_payload_s, set->network, set->status, set->name, set->step);
-
- set->step = kt_tacocat_socket_step_send_packet_e;
+ kt_tacocat_send_step_encode(main, set);
}
if (set->step == kt_tacocat_socket_step_send_packet_e) {
- size_t written = 0;
-
- {
- const size_t original = set->socket.size_write;
-
- set->socket.size_write = set->buffer.used;
-
- set->status = f_socket_write_stream(&set->socket, f_socket_flag_signal_not_e, (void *) set->buffer.string, &written);
-
- set->socket.size_write = original;
-
- macro_kt_tacocat_handle_send_process_error_exit_1(main, 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.
-
- set->size_done += written;
-
- set->status = F_okay;
- set->step = kt_tacocat_socket_step_send_wait_e;
+ kt_tacocat_send_step_packet(main, set);
// Wait for packet received confirmation.
return F_done_not;
}
if (set->step == kt_tacocat_socket_step_send_wait_e) {
- // @todo process/validate the received response.
-
- // 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->step = kt_tacocat_socket_step_send_done_e;
- }
- else {
- set->status = F_okay;
- set->step = kt_tacocat_socket_step_send_wait_e;
-
- return F_done_not;
- }
+ if (kt_tacocat_send_step_wait(main, set) == F_complete_not) return F_done_not;
}
if (set->step == kt_tacocat_socket_step_send_done_e) {
- //@todo send done packet.
- set->status = f_file_close(&set->file);
-
- if (F_status_is_error(set->status)) {
- kt_tacocat_print_warning_on_file(&main->program.warning, F_status_debug_source_d, kt_tacocat_send_done_s, set->network, set->status, set->name, f_file_operation_close_s);
- }
-
- set->status = f_socket_disconnect(&set->socket, f_socket_close_fast_e);
-
- if (F_status_is_error(set->status)) {
- kt_tacocat_print_warning_on_file(&main->program.warning, F_status_debug_source_d, kt_tacocat_send_done_s, set->network, set->status, set->name, f_file_operation_close_s);
- }
-
- set->step = 0;
- set->socket.id_data = -1;
- set->status = F_okay;
+ kt_tacocat_send_step_done(main, set);
return F_done;
}
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_build_
+ void kt_tacocat_send_step_build(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return;
+
+ {
+ f_state_t state = main->setting.state;
+ state.data = &set->write_state;
+
+ fl_fss_payload_header_map(set->abstruses, &set->headers, &state);
+
+ if (F_status_is_error(state.status)) {
+ set->status = state.status;
+
+ kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_build_s, set->network, set->status, set->name);
+
+ return;
+ }
+ }
+
+ set->write_state.cache->used = 0;
+
+ set->status = f_random_array_shuffle(0, set->headers.used, sizeof(f_string_map_t), set->write_state.cache, (void *) set->headers.array);
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_build_s, set->network, set->status, set->name);
+
+ return;
+ }
+
+ set->step = kt_tacocat_socket_step_send_header_e;
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_send_step_build_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step build functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_build_h
+#define _kt_tacocat_send_step_build_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the build step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_random_array_shuffle()
+ * Errors (with error bit) from: fl_fss_payload_header_map()
+ *
+ * @see f_random_array_shuffle()
+ * @see fl_fss_payload_header_map()
+ */
+#ifndef _di_kt_tacocat_send_step_build_
+ extern void kt_tacocat_send_step_build(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_build_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_build_h
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_check_
+ void kt_tacocat_send_step_check(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return;
+
+ // @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->step = kt_tacocat_socket_step_send_encode_e;
+ }
+#endif // _di_kt_tacocat_send_step_check_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step check functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_check_h
+#define _kt_tacocat_send_step_check_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the check step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ */
+#ifndef _di_kt_tacocat_send_step_check_
+ extern void kt_tacocat_send_step_check(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_check_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_check_h
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_done_
+ void kt_tacocat_send_step_done(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return;
+
+ //@todo send done packet.
+
+ set->status = f_file_close(&set->file);
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_warning_on_file(&main->program.warning, F_status_debug_source_d, kt_tacocat_send_done_s, set->network, set->status, set->name, f_file_operation_close_s);
+ }
+
+ set->status = f_socket_disconnect(&set->socket, f_socket_close_fast_e);
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_warning_on_file(&main->program.warning, F_status_debug_source_d, kt_tacocat_send_done_s, set->network, set->status, set->name, f_file_operation_close_s);
+ }
+
+ set->step = 0;
+ set->socket.id_data = -1;
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_send_step_done_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step done functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_done_h
+#define _kt_tacocat_send_step_done_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the done step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ */
+#ifndef _di_kt_tacocat_send_step_done_
+ extern void kt_tacocat_send_step_done(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_done_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_done_h
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_encode_
+ void kt_tacocat_send_step_encode(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return;
+
+ {
+ const f_number_unsigned_t original = set->buffer.used;
+
+ set->buffer.used = 0;
+
+ // @todo there will need to be checks for max-size and the payload size, shrinking the payload if the header + payload is too large.
+ // @todo if the header file is so large that the payload is smaller than a reasonable minumum (say 32 bytes), then this is a problem and throw a too large/small error.
+ set->status = f_fss_simple_packet_encode(F_fss_simple_packet_endian_d, original, &set->buffer);
+
+ set->buffer.used = original;
+ }
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_encode_s, set->network, set->status, set->name);
+
+ return;
+ }
+
+ set->step = kt_tacocat_socket_step_send_packet_e;
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_send_step_encode_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step encode functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_encode_h
+#define _kt_tacocat_send_step_encode_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the encode step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ *
+ * F_done (with error bit) on error that cannot continue, such as out of memory.
+ * F_too_large (with error bit) on file too large.
+ *
+ * Errors (with error bit) from: f_file_open()
+ * Errors (with error bit) from: f_file_size_by_id()
+ * Errors (with error bit) from: f_memory_array_increase_by()
+ *
+ * @see f_file_open()
+ * @see f_file_size_by_id()
+ * @see f_memory_array_increase_by()
+ */
+#ifndef _di_kt_tacocat_send_step_encode_
+ extern void kt_tacocat_send_step_encode(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_encode_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_encode_h
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_file_
+ void kt_tacocat_send_step_file(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return;
+
+ set->status = f_string_dynamic_append(f_fss_payload_object_payload_s, &set->buffer);
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_append(f_fss_payload_object_end_s, &set->buffer);
+ }
+
+ // Always reset the seek position in case a retry happened after the file block is read.
+ if (F_status_is_error_not(set->status)) {
+ off_t seeked = 0;
+
+ set->status = f_file_seek(set->file, SEEK_SET, set->size_done, &seeked);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_file_read_block(set->file, &set->buffer);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_terminate_after(&set->buffer);
+ }
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_file_s, set->network, set->status, set->name);
+
+ return;
+ }
+
+ set->retry = 0;
+ set->step = kt_tacocat_socket_step_send_check_e;
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_send_step_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step file functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_file_h
+#define _kt_tacocat_send_step_file_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the file step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_file_read_block()
+ * Errors (with error bit) from: f_file_seek()
+ * Errors (with error bit) from: f_string_dynamic_append()
+ * Errors (with error bit) from: f_string_dynamic_terminate_after()
+ *
+ * @see f_file_read_block()
+ * @see f_file_seek()
+ * @see f_string_dynamic_append()
+ * @see f_string_dynamic_terminate_after()
+ */
+#ifndef _di_kt_tacocat_send_step_file_
+ extern void kt_tacocat_send_step_file(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_file_h
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_header_
+ void kt_tacocat_send_step_header(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return;
+
+ // @todo this needs to check the current status, accordingly (for when multiple blocks are being sent).
+
+ // Reserve the FSS Packet header, which will be calculated just before sending.
+ set->buffer.used = 5;
+ memset(set->buffer.string, 0, 5);
+
+ set->status = f_string_dynamic_append_nulless(f_fss_payload_comment_header_begin_s, &set->buffer);
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_append_nulless(f_fss_payload_comment_header_s, &set->buffer);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_append_nulless(f_fss_payload_comment_header_end_s, &set->buffer);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_append_nulless(f_fss_payload_object_header_s, &set->buffer);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_append_nulless(f_fss_payload_object_end_s, &set->buffer);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ for (f_number_unsigned_t i = 0; i < set->headers.used; ++i) {
+
+ set->status = f_string_dynamic_append_nulless(set->headers.array[i].key, &set->buffer);
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_append_nulless(f_fss_extended_open_s, &set->buffer);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_append_nulless(set->headers.array[i].value, &set->buffer);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_string_dynamic_append_nulless(f_fss_extended_close_s, &set->buffer);
+ }
+ else {
+ break;
+ }
+ } // for
+ }
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_combine_s, set->network, set->status, set->name);
+
+ return;
+ }
+
+ set->step = kt_tacocat_socket_step_send_file_e;
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_send_step_header_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step header functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_header_h
+#define _kt_tacocat_send_step_header_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the header step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_string_dynamic_append_nulless()
+ *
+ * @see f_string_dynamic_append_nulless()
+ */
+#ifndef _di_kt_tacocat_send_step_header_
+ extern void kt_tacocat_send_step_header(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_header_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_header_h
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_packet_
+ void kt_tacocat_send_step_packet(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return;
+
+ {
+ size_t written = 0;
+
+ {
+ const size_t original = set->socket.size_write;
+
+ set->socket.size_write = set->buffer.used;
+
+ set->status = f_socket_write_stream(&set->socket, f_socket_flag_signal_not_e, (void *) set->buffer.string, &written);
+
+ set->socket.size_write = original;
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_packet_s, set->network, set->status, set->name);
+
+ return;
+ }
+ }
+
+ // @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.
+
+ set->size_done += written;
+ }
+
+ set->step = kt_tacocat_socket_step_send_wait_e;
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_send_step_packet_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step packet functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_packet_h
+#define _kt_tacocat_send_step_packet_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the packet step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_socket_write_stream()
+ *
+ * @see f_socket_write_stream()
+ */
+#ifndef _di_kt_tacocat_send_step_packet_
+ extern void kt_tacocat_send_step_packet(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_packet_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_packet_h
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_size_
+ void kt_tacocat_send_step_size(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return;
+
+ if (set->file.id == -1) {
+ set->status = f_file_open(set->name, F_file_mode_all_r_d, &set->file);
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on_file_receive(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_open_s);
+
+ return;
+ }
+ }
+
+ // Total is used here to explicitly pass a pointer of off_t rather than a pointer of size_t cast to an off_t.
+ {
+ off_t total = 0;
+
+ set->status = f_file_size_by_id(set->file, &total);
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on_file_receive(&main->program.error, F_status_debug_source_d, kt_tacocat_send_size_s, set->network, set->status, set->name, f_file_operation_open_s);
+
+ return;
+ }
+
+ if ((f_number_unsigned_t) total > F_number_t_size_unsigned_d) {
+ set->status = F_status_set_error(F_too_large);
+
+ kt_tacocat_print_error_on_file_too_large(&main->program.error, set->name, kt_tacocat_send_size_s, set->network, F_number_t_size_unsigned_d, set->abstruses.array[4].value.is.a_unsigned);
+
+ return;
+ }
+
+ set->abstruses.array[3].value.is.a_unsigned = 0;
+ set->size_total = (f_number_unsigned_t) total;
+
+ if (total) {
+ if (set->size_total < set->file.size_read) {
+ set->abstruses.array[2].value.is.a_unsigned = set->size_total;
+ set->abstruses.array[4].value.is.a_unsigned = 1;
+ }
+ else {
+ set->abstruses.array[2].value.is.a_unsigned = set->file.size_read;
+ set->abstruses.array[4].value.is.a_unsigned = set->size_total / set->file.size_read;
+
+ if (set->abstruses.array[4].value.is.a_unsigned % set->file.size_read) {
+ ++set->abstruses.array[4].value.is.a_unsigned;
+ }
+ }
+ }
+ else {
+ set->abstruses.array[2].value.is.a_unsigned = set->size_total;
+ set->abstruses.array[4].value.is.a_unsigned = 1;
+ }
+ }
+
+ set->status = f_memory_array_increase_by(set->abstruses.array[4].value.is.a_unsigned, sizeof(f_number_unsigned_t), (void **) &set->parts.array, &set->parts.used, &set->parts.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, F_status_debug_source_d, kt_tacocat_send_size_s, set->network, set->status, set->name);
+
+ return;
+ }
+
+ set->step = kt_tacocat_socket_step_send_build_e;
+ }
+#endif // _di_kt_tacocat_send_step_size_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step size functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_size_h
+#define _kt_tacocat_send_step_size_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the size step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ *
+ * F_done (with error bit) on error that cannot continue, such as out of memory.
+ * F_too_large (with error bit) on file too large.
+ *
+ * Errors (with error bit) from: f_file_open()
+ * Errors (with error bit) from: f_file_size_by_id()
+ * Errors (with error bit) from: f_memory_array_increase_by()
+ *
+ * @see f_file_open()
+ * @see f_file_size_by_id()
+ * @see f_memory_array_increase_by()
+ */
+#ifndef _di_kt_tacocat_send_step_size_
+ extern void kt_tacocat_send_step_size(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_size_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_size_h
--- /dev/null
+#include "../../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_send_step_wait_
+ f_status_t kt_tacocat_send_step_wait(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set || F_status_is_error(set->status)) return F_status_set_error(F_parameter);
+
+ // @todo process/validate the received response.
+
+ set->status = F_okay;
+
+ // 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->step = kt_tacocat_socket_step_send_done_e;
+
+ return F_complete;
+ }
+
+ set->step = kt_tacocat_socket_step_send_wait_e;
+
+ return F_complete_not;
+ }
+#endif // _di_kt_tacocat_send_step_wait_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides send step wait functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_send_step_wait_h
+#define _kt_tacocat_send_step_wait_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the wait step of a send request.
+ *
+ * This prints on error.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * Must not be NULL.
+ *
+ * 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:
+ * F_okay on success.
+ *
+ * @return
+ * F_complete on success and entire payload is sent.
+ * F_complete_not on success and the payload is not entirely sent.
+ *
+ * F_parameter (with error bit) on invalid parameter.
+ */
+#ifndef _di_kt_tacocat_send_step_wait_
+ extern f_status_t kt_tacocat_send_step_wait(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_step_wait_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_send_step_wait_h
#include <program/kevux/tools/tacocat/main/process.h>
#include <program/kevux/tools/tacocat/main/receive.h>
#include <program/kevux/tools/tacocat/main/send.h>
+#include <program/kevux/tools/tacocat/main/send/step/build.h>
+#include <program/kevux/tools/tacocat/main/send/step/check.h>
+#include <program/kevux/tools/tacocat/main/send/step/done.h>
+#include <program/kevux/tools/tacocat/main/send/step/encode.h>
+#include <program/kevux/tools/tacocat/main/send/step/file.h>
+#include <program/kevux/tools/tacocat/main/send/step/header.h>
+#include <program/kevux/tools/tacocat/main/send/step/packet.h>
+#include <program/kevux/tools/tacocat/main/send/step/size.h>
+#include <program/kevux/tools/tacocat/main/send/step/wait.h>
#include <program/kevux/tools/tacocat/main/signal.h>
#include <program/kevux/tools/tacocat/main/thread.h>