This strongly moves in the direction of setting up sending and receiving the different packets.
This includes handling of multiple packet parts.
None of this is ready yet, but progress is being made.
There is currently a strong focus on getting the FSS Payload processing code wrapped up, working, and tested.
f_type_array
f_string
f_utf
+f_abstruse
f_color
f_console
f_compare
f_file
f_fss
f_network
+f_parse
f_path
f_pipe
f_print
f_random
+f_rip
f_signal
f_socket
f_status_string
build_libraries -lc
build_libraries-individual -lfll_error -lfll_fss -lfll_print -lfll_program
build_libraries-individual -lfl_conversion -lfl_fss -lfl_print -lfl_status_string
-build_libraries-individual -lf_color -lf_compare -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_network -lf_path -lf_pipe -lf_print -lf_random -lf_signal -lf_socket -lf_status_string -lf_string -lf_time -lf_type_array -lf_utf
+build_libraries-individual -lf_abstruse -lf_color -lf_compare -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_network -lf_parse -lf_path -lf_pipe -lf_print -lf_random -lf_rip -lf_signal -lf_socket -lf_status_string -lf_string -lf_time -lf_type_array -lf_utf
build_libraries-individual_thread -lf_thread
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library main/common.c main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c main/print/error.c main/print/message.c main/print/verbose.c main/print/warning.c main/process.c main/receive.c main/send.c main/signal.c main/tacocat.c main/thread.c
+build_sources_library main/common.c main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c main/print/error.c main/print/message.c main/print/verbose.c main/print/warning.c main/packet.c main/process.c main/receive.c main/send.c main/signal.c main/tacocat.c main/thread.c
-build_sources_headers main/common.h main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h main/print/error.h main/print/message.h main/print/verbose.h main/print/warning.h main/process.h main/receive.h main/send.h main/signal.h main/tacocat.h main/thread.h
+build_sources_headers main/common.h main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h main/print/error.h main/print/message.h main/print/verbose.h main/print/warning.h main/packet.h main/process.h main/receive.h main/send.h main/signal.h main/tacocat.h main/thread.h
build_sources_program main/main.c
defines -D_libcap_legacy_only_
defines-threadless -D_di_thread_support_
defines-thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_
+defines-individual_thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_
flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses -Wno-missing-braces
flags-thread -pthread
*
* kt_tacocat_packet_*_d:
* - headers: The number of header Objects in the abstruse to create for sending a packet (type, name, part, size, status, and total).
+ * - id_length: The length used to generate the random string for the transaction ID (must be less than 2^8, aka less than 256).
* - minimum: The minimum packet size, "header:\npayload:\n" = 17.
* - peek: The size to peek into the packet to get the initial information.
* - prebuffer: A size used to include during allocation to add additional space for the packet header and therefore help reduce the potential number of allocations.
#define kt_tacocat_allocation_large_d 0x800
#define kt_tacocat_allocation_small_d 0x80
- #define kt_tacocat_block_size_d 0xffff // @todo set this to something small like 0xff to easily test and design sending and receiving multiple parts.
+ #define kt_tacocat_block_size_d 0xffff
#define kt_tacocat_block_size_receive_d kt_tacocat_block_size_d
#define kt_tacocat_block_size_send_d kt_tacocat_block_size_d
#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?)).
#define kt_tacocat_max_maintain_d 0x100000 // 0x10^5 (Which is 1 Megabyte in base 16 (1 Megaxyte (MX)).
- #define kt_tacocat_packet_headers_d 0x7
+ #define kt_tacocat_packet_headers_d 0x8
+ #define kt_tacocat_packet_id_length_d 0x20
#define kt_tacocat_packet_minimum_d 0x11
#define kt_tacocat_packet_peek_d 0x40
#define kt_tacocat_packet_prebuffer_d 0x200
* 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 step kt_tacocat_socket_step_receive_control_e.
*
kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(method), kt_tacocat_receive_s, network, status, name); \
\
if (id_data) { \
- f_file_close_id(id_data); \
+ f_file_close_id(&(id_data)); \
} \
\
step = 0; \
return F_done_not; \
}
- #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); \
- \
- if (id_data) { \
- f_file_close_id(id_data); \
- } \
- \
- step = 0; \
- \
- return; \
- }
-
#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); \
* - extract: Process the loaded data, extracting the Header and Signature sections.
* - check: Check the loaded data, doing size checks, interpreting the status, and performing any signature checks.
* - write: Save the loaded Payload block to the file (write to the file).
+ * - next: Send "next" or "done" packet.
* - done: Done processing file.
*/
#ifndef _di_kt_tacocat_socket_step_receive_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_next_e,
kt_tacocat_socket_step_receive_done_e,
}; // enum
#endif // _di_kt_tacocat_socket_step_receive_e_
* Individual socket-specific steps for receiving.
*
* kt_tacocat_socket_step_send_*_e:
- * - none: No flags set.
- * - size: Determine the file size.
- * - header: Build and buffer the header.
- * - build: Build the header information.
- * - file: Buffer the file.
- * - check: Additional checks before sending, such as re-checking header size.
- * - encode: Encode entire packet.
- * - packet: Send the entire packet.
- * - done: The entire Packet is sent.
+ * - none: No flags set.
+ * - size: Determine the file size.
+ * - header: Build and buffer the header.
+ * - build: Build the header information.
+ * - file: Buffer the file.
+ * - check: Additional checks before sending, such as re-checking header size.
+ * - encode: Encode entire packet.
+ * - packet: Send the packet.
+ * - response: Wait for a response packet from the opposite end.
+ * - done: The entire Packet is sent.
*/
#ifndef _di_kt_tacocat_socket_step_send_e_
enum {
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_wait_e,
kt_tacocat_socket_step_send_done_e,
}; // enum
#endif // _di_kt_tacocat_socket_step_send_e_
"fll_program_parameter_process_verbosity",
"kt_tacocat_process_abstruse_initialize",
"kt_tacocat_process_socket_set_error_has",
+ "kt_tacocat_send_process_initialize",
"kt_tacocat_setting_load_address_port_extract",
"kt_tacocat_setting_load_send_receive_allocate",
};
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_send_process_initialize_e,
kt_tacocat_f_kt_tacocat_setting_load_address_port_extract_e,
kt_tacocat_f_kt_tacocat_setting_load_send_receive_allocate_e,
}; // enum
f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].header.string, &array[i].header.used, &array[i].header.size);
}
+ if (array[i].id.size) {
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].id.string, &array[i].id.used, &array[i].id.size);
+ }
+
if (array[i].name.size) {
f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].name.string, &array[i].name.used, &array[i].name.size);
}
* size_done: The size in bytes that are done being processed (generally used by send/write).
* 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.
+ * flag: A set of flags.
+ * step: The current step the socket set is operating under.
+ * retry: The current number of retries performed.
+ * part: The current active part number.
+ *
* file: The file structure.
* socket: Socket structure.
* status: The status of the socket operations.
uint16_t flag;
uint16_t step;
uint16_t retry;
+ f_number_unsigned_t part;
+
f_file_t file;
f_socket_t socket;
f_status_t status;
f_string_dynamic_t cache;
f_string_dynamic_t client;
f_string_dynamic_t header;
+ f_string_dynamic_t id;
f_string_dynamic_t name;
f_string_dynamic_t network;
f_fss_simple_packet_range_t packet;
- f_fss_payload_header_write_state_t write_state;
+ f_fss_payload_header_state_t write_state;
f_abstruse_maps_t abstruses;
f_string_maps_t headers;
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
f_fss_simple_packet_range_t_initialize, \
- f_fss_payload_header_write_state_t_initialize, \
+ f_fss_payload_header_state_t_initialize, \
f_abstruse_maps_t_initialize, \
f_string_maps_t_initialize, \
}
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
f_fss_simple_packet_range_t_initialize, \
- f_fss_payload_header_write_state_t_initialize, \
+ f_fss_payload_header_state_t_initialize, \
f_abstruse_maps_t_initialize, \
f_string_maps_t_initialize, \
}
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
f_fss_simple_packet_range_t_initialize, \
write_state, \
f_abstruse_maps_t_initialize, \
--- /dev/null
+#include "tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_packet_extract_
+ void kt_tacocat_packet_extract(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_string_static_t direction) {
+
+ if (!main || !set) return;
+
+ kt_tacocat_process_abstruse_initialize(main, set);
+
+ if (F_status_is_error(set->status)) {
+ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(kt_tacocat_process_abstruse_initialize), direction, set->network, set->status, set->name);
+
+ if (set->socket.id_data) {
+ f_file_close_id(&set->socket.id_data);
+ }
+
+ set->step = 0;
+
+ return;
+ }
+
+ // 0x1 = did not find payload, 0x2 = did not find header.
+ uint8_t found_not = 0x3;
+
+ for (f_number_unsigned_t i = 0; i < set->objects.used; ++i) {
+
+ if (f_compare_dynamic_partial_string(f_fss_payload_object_header_s.string, set->buffer, f_fss_payload_object_header_s.used, set->objects.array[i]) == F_equal_to) {
+ kt_tacocat_packet_extract_header(main, set, i, direction);
+
+ if (F_status_is_error(set->status)) {
+ // @todo handle F_packet error, setup the sending of an invalid packet response (things similar to this needs to be done in multiple places).
+ ++set->retry;
+
+ return;
+ }
+
+ found_not &= ~0x2;
+ }
+ else if (f_compare_dynamic_partial_string(f_fss_payload_object_signature_s.string, set->buffer, f_fss_payload_object_signature_s.used, set->objects.array[i]) == F_equal_to) {
+ kt_tacocat_packet_extract_signature(main, set, i, direction);
+
+ if (F_status_is_error(set->status)) {
+ ++set->retry;
+
+ return;
+ }
+ }
+ else if (f_compare_dynamic_partial_string(f_fss_payload_object_payload_s.string, set->buffer, f_fss_payload_object_payload_s.used, set->objects.array[i]) == F_equal_to) {
+ if (found_not & 0x1) {
+ set->packet.payload = set->contents.array[i].array[0];
+ found_not &= ~0x1;
+ }
+ }
+ } // for
+
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_packet_extract_
+
+#ifndef _di_kt_tacocat_packet_extract_header_
+ void kt_tacocat_packet_extract_header(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_number_unsigned_t at, const f_string_static_t direction) {
+
+ if (!main || !set) return;
+
+ if (set->objects.array[at].start > set->objects.array[at].stop || !set->contents.array[at].used) {
+ set->status = F_data_not;
+
+ return;
+ }
+
+ set->range = set->contents.array[at].array[0];
+
+ fll_fss_extended_read(set->buffer, &set->range, &set->objects_header, &set->contents_header, &set->objects_quoted_header, &set->contents_quoted_header, &set->objects_delimits_header, &set->contents_delimits_header, &set->state);
+
+ if (F_status_is_error(set->state.status)) {
+ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(fll_fss_extended_read), direction, set->network, set->status, set->name);
+
+ set->status = set->state.status;
+
+ return;
+ }
+
+ switch (set->state.status) {
+ case F_okay:
+ case F_okay_stop:
+ case F_okay_eos:
+ break;
+
+ default:
+ set->status = F_data_not;
+
+ return;
+ }
+
+ f_number_unsigned_t i = 0;
+
+ for (; i < set->objects_header.used; ++i) {
+
+ // Index 0 is the status.
+ if (f_compare_dynamic_partial_string(f_fss_payload_object_status_s.string, set->buffer, f_fss_payload_object_status_s.used, set->objects_header.array[i]) == F_equal_to) {
+
+ // Require Content to exist.
+ if (!set->contents_header.array[i].used) {
+ set->abstruses.array[0].value.type = f_abstruse_none_e;
+
+ continue;
+ }
+
+ set->abstruses.array[0].value.type = f_abstruse_range_e;
+ set->abstruses.array[0].value.is.a_range = set->contents_header.array[i].array[0];
+ }
+
+ // Index 1 is the type.
+ else if (f_compare_dynamic_partial_string(f_fss_payload_object_type_s.string, set->buffer, f_fss_payload_object_type_s.used, set->objects_header.array[i]) == F_equal_to) {
+
+ // Require Content to exist.
+ if (!set->contents_header.array[i].used) {
+ set->abstruses.array[1].value.type = f_abstruse_none_e;
+
+ continue;
+ }
+
+ set->abstruses.array[1].value.type = f_abstruse_range_e;
+ set->abstruses.array[1].value.is.a_range = set->contents_header.array[i].array[0];
+ }
+
+ // Index 2 is the length.
+ else if (f_compare_dynamic_partial_string(f_fss_payload_object_length_s.string, set->buffer, f_fss_payload_object_length_s.used, set->objects_header.array[i]) == F_equal_to) {
+
+ // Require Content to exist.
+ if (!set->contents_header.array[i].used) {
+ set->abstruses.array[2].value.type = f_abstruse_none_e;
+
+ continue;
+ }
+
+ set->abstruses.array[2].value.type = f_abstruse_range_e;
+ set->abstruses.array[2].value.is.a_range = set->contents_header.array[i].array[0];
+ }
+
+ // Index 3 is the part.
+ else if (f_compare_dynamic_partial_string(f_fss_payload_object_part_s.string, set->buffer, f_fss_payload_object_part_s.used, set->objects_header.array[i]) == F_equal_to) {
+
+ // Require Content to exist.
+ if (!set->contents_header.array[i].used) {
+ set->abstruses.array[3].value.type = f_abstruse_none_e;
+
+ continue;
+ }
+
+ set->abstruses.array[3].value.type = f_abstruse_range_e;
+ set->abstruses.array[3].value.is.a_range = set->contents_header.array[i].array[0];
+ }
+
+ // Index 4 is the total number of packets (based on block size).
+ else if (f_compare_dynamic_partial_string(f_fss_payload_object_total_s.string, set->buffer, f_fss_payload_object_total_s.used, set->objects_header.array[i]) == F_equal_to) {
+
+ // Require Content to exist.
+ if (!set->contents_header.array[i].used) {
+ set->abstruses.array[4].value.type = f_abstruse_none_e;
+
+ continue;
+ }
+
+ set->abstruses.array[4].value.type = f_abstruse_range_e;
+ set->abstruses.array[4].value.is.a_range = set->contents_header.array[i].array[0];
+ }
+
+ // Index 5 is the name (file name).
+ else if (f_compare_dynamic_partial_string(f_fss_payload_object_name_s.string, set->buffer, f_fss_payload_object_name_s.used, set->objects_header.array[i]) == F_equal_to) {
+
+ // Require Content to exist.
+ if (!set->contents_header.array[i].used) {
+ set->abstruses.array[5].value.type = f_abstruse_none_e;
+
+ continue;
+ }
+
+ set->abstruses.array[5].value.type = f_abstruse_range_e;
+ set->abstruses.array[5].value.is.a_range = set->contents_header.array[i].array[0];
+ }
+
+ // Index 6 is the salt.
+ else if (f_compare_dynamic_partial_string(kt_tacocat_salt_s.string, set->buffer, kt_tacocat_salt_s.used, set->objects_header.array[i]) == F_equal_to) {
+
+ // Require Content to exist.
+ if (!set->contents_header.array[i].used) {
+ set->abstruses.array[6].value.type = f_abstruse_none_e;
+
+ continue;
+ }
+
+ set->abstruses.array[6].value.type = f_abstruse_range_e;
+ set->abstruses.array[6].value.is.a_range = set->contents_header.array[i].array[0];
+ }
+
+ // Index 7 is the transaction id.
+ else if (f_compare_dynamic_partial_string(f_fss_payload_object_id_s.string, set->buffer, f_fss_payload_object_id_s.used, set->objects_header.array[i]) == F_equal_to) {
+
+ // Require Content to exist.
+ if (!set->contents_header.array[i].used) {
+ set->abstruses.array[7].value.type = f_abstruse_none_e;
+
+ continue;
+ }
+
+ set->abstruses.array[7].value.type = f_abstruse_range_e;
+ set->abstruses.array[7].value.is.a_range = set->contents_header.array[i].array[0];
+ }
+ } // for
+
+ // Convert the status code.
+ if (set->abstruses.array[0].value.type) {
+ const f_number_unsigned_t length = set->abstruses.array[0].value.is.a_range.stop - set->abstruses.array[0].value.is.a_range.start + 1;
+ char buffer[length];
+ f_status_t status = F_false;
+
+ memcpy(buffer, set->buffer.string + set->abstruses.array[0].value.is.a_range.start, length);
+
+ const f_string_static_t status_string = macro_f_string_static_t_initialize_1(buffer, 0, length);
+
+ set->status = fl_status_string_from(status_string, &status);
+
+ if (set->status == F_okay) {
+ set->abstruses.array[0].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[0].value.is.a_unsigned = (f_number_unsigned_t) status;
+ }
+ else {
+ kt_tacocat_print_error_on_packet_header_value_invalid(&main->program.error, direction, set->network, set->status, set->name, set->buffer, set->objects.array[at], set->abstruses.array[6].value.is.a_range);
+
+ set->abstruses.array[0].value.type = f_abstruse_none_e;
+ set->abstruses.array[0].value.is.a_unsigned = 0;
+
+ set->status = F_status_set_error(F_packet);
+ }
+ }
+
+ // Convert the type.
+ if (set->abstruses.array[1].value.type) {
+ if (f_compare_dynamic_partial_string(kt_tacocat_file_s.string, set->buffer, kt_tacocat_file_s.used, set->abstruses.array[1].value.is.a_range) == F_equal_to) {
+ set->abstruses.array[1].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[1].value.is.a_unsigned = (f_number_unsigned_t) kt_tacocat_packet_type_file_e;
+ }
+ else if (f_compare_dynamic_partial_string(kt_tacocat_done_s.string, set->buffer, kt_tacocat_done_s.used, set->abstruses.array[1].value.is.a_range) == F_equal_to) {
+ set->abstruses.array[1].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[1].value.is.a_unsigned = (f_number_unsigned_t) kt_tacocat_packet_type_done_e;
+ }
+ else if (f_compare_dynamic_partial_string(kt_tacocat_next_s.string, set->buffer, kt_tacocat_next_s.used, set->abstruses.array[1].value.is.a_range) == F_equal_to) {
+ set->abstruses.array[1].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[1].value.is.a_unsigned = (f_number_unsigned_t) kt_tacocat_packet_type_next_e;
+ }
+ else if (f_compare_dynamic_partial_string(kt_tacocat_resend_s.string, set->buffer, kt_tacocat_resend_s.used, set->abstruses.array[1].value.is.a_range) == F_equal_to) {
+ set->abstruses.array[1].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[1].value.is.a_unsigned = (f_number_unsigned_t) kt_tacocat_packet_type_resend_e;
+ }
+ else {
+ set->status = F_status_set_error(F_found_not);
+
+ kt_tacocat_print_error_on_packet_header_value_invalid(&main->program.error, direction, set->network, set->status, set->name, set->buffer, set->objects.array[at], set->abstruses.array[6].value.is.a_range);
+
+ set->abstruses.array[1].value.type = f_abstruse_none_e;
+ set->abstruses.array[1].value.is.a_unsigned = 0;
+
+ set->status = F_status_set_error(F_packet);
+
+ return;
+ }
+ }
+
+ // Convert the length, part, and total.
+ {
+ f_number_unsigned_t number = 0;
+
+ for (i = 2; i < 5; ++i) {
+
+ if (!set->abstruses.array[i].value.type) continue;
+
+ set->status = fl_conversion_dynamic_partial_to_unsigned(fl_conversion_data_base_10_c, set->buffer, set->abstruses.array[i].value.is.a_range, &number);
+
+ if (set->status == F_okay) {
+ set->abstruses.array[i].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[i].value.is.a_unsigned = number;
+ }
+ else {
+ kt_tacocat_print_error_on_packet_header_value_invalid(&main->program.error, direction, set->network, set->status, set->name, set->buffer, set->objects.array[at], set->abstruses.array[6].value.is.a_range);
+
+ set->abstruses.array[i].value.type = f_abstruse_none_e;
+ set->abstruses.array[i].value.is.a_unsigned = 0;
+
+ set->status = F_status_set_error(F_packet);
+ }
+ } // for
+ }
+
+ set->abstruses.used = kt_tacocat_packet_headers_d;
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_packet_extract_header_
+
+#ifndef _di_kt_tacocat_packet_extract_signature_
+ void kt_tacocat_packet_extract_signature(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_number_unsigned_t at, const f_string_static_t direction) {
+
+ if (!main || !set) return;
+
+ if (set->objects.array[at].start > set->objects.array[at].stop || !set->contents.array[at].used) {
+ set->status = F_data_not;
+
+ return;
+ }
+
+ set->range = set->contents.array[at].array[0];
+
+ fll_fss_extended_read(set->buffer, &set->range, &set->objects_signature, &set->contents_signature, &set->objects_quoted_header, &set->contents_quoted_header, &set->objects_delimits_signature, &set->contents_delimits_signature, &set->state);
+
+ if (F_status_is_error(set->state.status)) {
+ kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(fll_fss_extended_read), direction, set->network, set->status, set->name);
+
+ set->status = set->state.status;
+
+ return;
+ }
+
+ // @todo maybe index 8 and beyond in the abstruse shall represent signatures?
+
+ set->status = F_okay;
+ }
+#endif // _di_kt_tacocat_packet_extract_signature_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _kt_tacocat_packet_h
+#define _kt_tacocat_packet_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Process the header and signature strings, extracting the data.
+ *
+ * Another function should perform some of the validation on the header.
+ * @todo This other function needs to return a status code such as F_continue to designate to continue to the next iteration.
+ * Ideally, the flag will be set to how to continue, such as "continue loading the entire payload".
+ * This situation would arise when the payload needs to be validated, such as the size.
+ *
+ * @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:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_memory_array_increase_by().
+ * Errors (with error bit) from: kt_tacocat_packet_extract_header().
+ * Errors (with error bit) from: kt_tacocat_packet_extract_signature().
+ * @param direction
+ * The string representing the direction and is used for error handling.
+ * This is generally either kt_tacocat_receive_s or kt_tacocat_send_s.
+ *
+ * @see f_memory_array_increase_by()
+ * @see kt_tacocat_packet_extract_header()
+ * @see kt_tacocat_packet_extract_signature()
+ */
+#ifndef _di_kt_tacocat_packet_extract_
+ extern void kt_tacocat_packet_extract(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_string_static_t direction);
+#endif // _di_kt_tacocat_packet_extract_
+
+/**
+ * Extract the header strings using the given index for an Object and Content.
+ *
+ * The positions in the abstruse are hard-coded with specific representations.
+ *
+ * Index Positions:
+ * - 0: Status string (such as F_okay).
+ * - 1: Type string (type of packet).
+ * - 2: Length number (the length of the Payload section).
+ * - 3: Packet part number.
+ * - 4: Total packet parts number.
+ * - 5: Name string (file name).
+ * - 6: Salt string (for making packet unique, if encrypted, signed, or something similar).
+ * - 7: Transaction ID (Can be anything, generally unique or port number).
+ *
+ * @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:
+ * F_okay on success.
+ * F_data_not on success, but no data to process.
+ *
+ * F_packet (with error bit) on invalid packet header.
+ *
+ * Errors (with error bit) from: fll_fss_extended_read().
+ * @param at
+ * The index position representing which Object and Contents set to use.
+ * @param direction
+ * The string representing the direction and is used for error handling.
+ * This is generally either kt_tacocat_receive_s or kt_tacocat_send_s.
+ *
+ * @see fll_fss_extended_read()
+ */
+#ifndef _di_kt_tacocat_packet_extract_header_
+ extern void kt_tacocat_packet_extract_header(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_number_unsigned_t at, const f_string_static_t direction);
+#endif // _di_kt_tacocat_packet_extract_header_
+
+/**
+ * Extract the signature strings using the given index for an Object and Content.
+ *
+ * @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:
+ * F_okay on success.
+ * @param direction
+ * The string representing the direction and is used for error handling.
+ * This is generally either kt_tacocat_receive_s or kt_tacocat_send_s.
+ * @param at
+ * The index position representing which Object and Contents set to use.
+ */
+#ifndef _di_kt_tacocat_packet_extract_signature_
+ extern void kt_tacocat_packet_extract_signature(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_number_unsigned_t at, const f_string_static_t direction);
+#endif // _di_kt_tacocat_packet_extract_signature_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_packet_h
fl_print_format("%[' with 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("%[' is invalid for Object '%]", 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, buffer, object, print->set->notable);
+ fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->set->notable, buffer, object, print->set->notable);
fl_print_format("%[' and Content '%]", 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, buffer, content, print->set->notable);
+ fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->set->notable, buffer, content, print->set->notable);
fl_print_format("%[' with a status code of %]", print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format(f_string_format_ul_single_s.string, print->to, print->set->notable, status, print->set->notable);
fl_print_format("%[.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
f_file_stream_lock(print->to);
fl_print_format("%[%QUnknown or invalid port number%] ", print->to, print->set->error, print->prefix, print->set->error);
- fl_print_format("%[%/Q%]", print->to, print->set->notable, address, range, print->set->notable);
+ fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->set->notable, address, range, print->set->notable);
fl_print_format(" %[from the address '%]", 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, address, print->set->notable);
fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
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;
+ set->abstruses.array[5].value.is.a_dynamic.size = 0;
// Index 6 is the salt.
set->abstruses.array[6].key = kt_tacocat_salt_s;
set->abstruses.array[6].value.type = f_abstruse_unsigned_e;
+ // Index 7 is the transaction id.
+ set->abstruses.array[7].key = f_fss_payload_object_id_s;
+ set->abstruses.array[7].value.type = f_abstruse_dynamic_e;
+ set->abstruses.array[7].value.is.a_dynamic = set->id;
+ set->abstruses.array[7].value.is.a_dynamic.size = 0;
+
{
long salt = 0;
set->abstruses.array[6].value.is.a_unsigned = (f_number_unsigned_t) salt;
}
- set->abstruses.used = 7;
+ set->abstruses.used = kt_tacocat_packet_headers_d;
}
#endif // _di_kt_tacocat_process_abstruse_initialize_
}
// Skip if status from poll is an error or is F_time_out.
- if (main->setting.active_receive >> 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;
if (!(set->step)) {
kt_tacocat_print_message_receive_operation_received(&main->program.message, *set);
- set->abstruses.used = 0;
- set->buffer.used = 0;
- set->cache.used = 0;
- set->header.used = 0;
- set->headers.used = 0;
- set->objects.used = 0;
- set->contents.used = 0;
- set->objects_delimits.used = 0;
- set->contents_delimits.used = 0;
- set->comments.used = 0;
- set->retry = 0;
- set->size_done = 0;
- set->size_total = 0;
- set->file.size_read = set->size_block;
- set->socket.size_read = kt_tacocat_packet_read_d;
- set->socket.id_data = -1;
- set->range.start = 1;
- set->range.stop = 0;
- set->state.status = F_none;
- set->status = F_none;
- set->packet.control = 0;
- set->packet.size = 0;
- set->packet.payload.start = 1;
- set->packet.payload.stop = 0;
- set->step = kt_tacocat_socket_step_receive_control_e;
- set->flag = 0;
+ kt_tacocat_receive_process_initialize(main, set);
++main->setting.active_receive;
}
// Make sure the buffer is large enough for payload processing block reads.
set->status = f_memory_array_increase_by(set->socket.size_read, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
- macro_kt_receive_process_handle_error_exit_1(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_1(main, f_memory_array_increase_by, set->network, set->status, set->name, set->flag, set->socket.id_data);
set->retry = 0;
set->buffer.used = 0;
size_t length_read = 0;
set->status = f_socket_read_stream(&set->socket, 0, (void *) (set->buffer.string + set->buffer.used), &length_read);
- macro_kt_receive_process_handle_error_exit_1(main, f_socket_read_stream, set->network, set->status, set->name, set->flag, &set->socket.id_data);
+ macro_kt_receive_process_handle_error_exit_1(main, f_socket_read_stream, set->network, set->status, set->name, set->flag, set->socket.id_data);
if (length_read) {
set->retry = 0;
}
if (set->step == kt_tacocat_socket_step_receive_extract_e) {
- kt_tacocat_receive_process_extract(main, set);
+ kt_tacocat_packet_extract(main, set, kt_tacocat_receive_s);
if (F_status_is_error(set->status)) return F_data_not;
- set->step = kt_tacocat_socket_step_receive_write_e;
+ set->step = kt_tacocat_socket_step_receive_check_e;
}
if (set->step == kt_tacocat_socket_step_receive_check_e) {
- // @todo
+ if (set->parts.used) {
+ // @todo determine type of packet and process.
+ }
+ else {
+ // @todo the packet should only be a 'file' type for the first packet.
+ if (set->abstruses.array[4].value.type == f_abstruse_unsigned_e) {
+ set->parts.used = 0;
+
+ 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);
+ macro_kt_receive_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->name, set->flag, set->socket.id_data);
+
+ memset(set->parts.array, 0, sizeof(f_number_unsigned_t));
+
+ set->parts.used = set->abstruses.array[4].value.is.a_unsigned;
+ }
+ else {
+ // @todo error.
+ }
+
+ if (set->abstruses.array[3].value.type == f_abstruse_unsigned_e) {
+ set->part = set->abstruses.array[3].value.is.a_unsigned;
+ }
+ else {
+ // @todo error
+ }
+ }
set->step = kt_tacocat_socket_step_receive_write_e;
}
f_file_close(&set->file);
set->buffer.used = 0;
+ set->step = kt_tacocat_socket_step_receive_next_e;
+ }
+
+ if (set->step == kt_tacocat_socket_step_receive_next_e) {
+ // @todo
+
set->step = kt_tacocat_socket_step_receive_done_e;
}
}
#endif // _di_kt_tacocat_receive_process_control_
-#ifndef _di_kt_tacocat_receive_process_extract_
- void kt_tacocat_receive_process_extract(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+#ifndef _di_kt_tacocat_receive_process_initialize_
+ void kt_tacocat_receive_process_initialize(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
if (!main || !set) return;
- kt_tacocat_process_abstruse_initialize(main, set);
-
- if (F_status_is_error(set->status)) {
- 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.
- uint8_t found_not = 0x3;
-
- for (f_number_unsigned_t i = 0; i < set->objects.used; ++i) {
-
- if (f_compare_dynamic_partial_string(f_fss_payload_object_header_s.string, set->buffer, f_fss_payload_object_header_s.used, set->objects.array[i]) == F_equal_to) {
- kt_tacocat_receive_process_extract_header(main, set, i);
-
- if (F_status_is_error(set->status)) {
- // @todo handle F_packet error, setup the sending of an invalid packet response (things similar to this needs to be done in multiple places).
- ++set->retry;
-
- return;
- }
-
- found_not &= ~0x2;
- }
- else if (f_compare_dynamic_partial_string(f_fss_payload_object_signature_s.string, set->buffer, f_fss_payload_object_signature_s.used, set->objects.array[i]) == F_equal_to) {
- kt_tacocat_receive_process_extract_signature(main, set, i);
-
- if (F_status_is_error(set->status)) {
- ++set->retry;
-
- return;
- }
- }
- else if (f_compare_dynamic_partial_string(f_fss_payload_object_payload_s.string, set->buffer, f_fss_payload_object_payload_s.used, set->objects.array[i]) == F_equal_to) {
- if (found_not & 0x1) {
- set->packet.payload = set->contents.array[i].array[0];
- found_not &= ~0x1;
- }
- }
- } // for
-
- set->status = F_okay;
- }
-#endif // _di_kt_tacocat_receive_process_extract_
-
-#ifndef _di_kt_tacocat_receive_process_extract_header_
- void kt_tacocat_receive_process_extract_header(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_number_unsigned_t at) {
-
- if (!main || !set) return;
-
- if (set->objects.array[at].start > set->objects.array[at].stop || !set->contents.array[at].used) {
- set->status = F_data_not;
-
- return;
- }
-
- set->range = set->contents.array[at].array[0];
-
- fll_fss_extended_read(set->buffer, &set->range, &set->objects_header, &set->contents_header, &set->objects_quoted_header, &set->contents_quoted_header, &set->objects_delimits_header, &set->contents_delimits_header, &set->state);
-
- if (F_status_is_error(set->state.status)) {
- kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(fll_fss_extended_read), kt_tacocat_receive_s, set->network, set->status, set->name);
-
- set->status = set->state.status;
-
- return;
- }
-
- switch (set->state.status) {
- case F_okay:
- case F_okay_stop:
- case F_okay_eos:
- break;
-
- default:
- set->status = F_data_not;
-
- return;
- }
-
- f_number_unsigned_t i = 0;
-
- for (; i < set->objects_header.used; ++i) {
-
- // Index 0 is the status.
- if (f_compare_dynamic_partial_string(f_fss_payload_object_status_s.string, set->buffer, f_fss_payload_object_status_s.used, set->objects_header.array[i]) == F_equal_to) {
-
- // Require Content to exist.
- if (!set->contents_header.array[i].used) {
- set->abstruses.array[0].value.type = f_abstruse_none_e;
-
- continue;
- }
-
- set->abstruses.array[0].key = f_fss_payload_object_status_s;
- set->abstruses.array[0].value.type = f_abstruse_range_e;
- set->abstruses.array[0].value.is.a_range = set->contents_header.array[i].array[0];
- }
-
- // Index 1 is the type.
- else if (f_compare_dynamic_partial_string(f_fss_payload_object_type_s.string, set->buffer, f_fss_payload_object_type_s.used, set->objects_header.array[i]) == F_equal_to) {
-
- // Require Content to exist.
- if (!set->contents_header.array[i].used) {
- set->abstruses.array[1].value.type = f_abstruse_none_e;
-
- continue;
- }
-
- set->abstruses.array[1].key = f_fss_payload_object_type_s;
- set->abstruses.array[1].value.type = f_abstruse_range_e;
- set->abstruses.array[1].value.is.a_range = set->contents_header.array[i].array[0];
- }
-
- // Index 2 is the length.
- else if (f_compare_dynamic_partial_string(f_fss_payload_object_length_s.string, set->buffer, f_fss_payload_object_length_s.used, set->objects_header.array[i]) == F_equal_to) {
-
- // Require Content to exist.
- if (!set->contents_header.array[i].used) {
- set->abstruses.array[2].value.type = f_abstruse_none_e;
-
- continue;
- }
-
- set->abstruses.array[2].key = f_fss_payload_object_length_s;
- set->abstruses.array[2].value.type = f_abstruse_range_e;
- set->abstruses.array[2].value.is.a_range = set->contents_header.array[i].array[0];
- }
-
- // Index 3 is the part.
- else if (f_compare_dynamic_partial_string(f_fss_payload_object_part_s.string, set->buffer, f_fss_payload_object_part_s.used, set->objects_header.array[i]) == F_equal_to) {
-
- // Require Content to exist.
- if (!set->contents_header.array[i].used) {
- set->abstruses.array[3].value.type = f_abstruse_none_e;
-
- continue;
- }
-
- set->abstruses.array[3].key = f_fss_payload_object_part_s;
- set->abstruses.array[3].value.type = f_abstruse_range_e;
- set->abstruses.array[3].value.is.a_range = set->contents_header.array[i].array[0];
- }
-
- // Index 4 is the total number of packets (based on block size).
- else if (f_compare_dynamic_partial_string(f_fss_payload_object_total_s.string, set->buffer, f_fss_payload_object_total_s.used, set->objects_header.array[i]) == F_equal_to) {
-
- // Require Content to exist.
- if (!set->contents_header.array[i].used) {
- set->abstruses.array[4].value.type = f_abstruse_none_e;
-
- continue;
- }
-
- set->abstruses.array[4].key = f_fss_payload_object_total_s;
- set->abstruses.array[4].value.type = f_abstruse_range_e;
- set->abstruses.array[4].value.is.a_range = set->contents_header.array[i].array[0];
- }
-
- // Index 5 is the name (file name).
- else if (f_compare_dynamic_partial_string(f_fss_payload_object_name_s.string, set->buffer, f_fss_payload_object_name_s.used, set->objects_header.array[i]) == F_equal_to) {
-
- // Require Content to exist.
- if (!set->contents_header.array[i].used) {
- set->abstruses.array[5].value.type = f_abstruse_none_e;
-
- continue;
- }
-
- set->abstruses.array[5].key = f_fss_payload_object_name_s;
- set->abstruses.array[5].value.type = f_abstruse_range_e;
- set->abstruses.array[5].value.is.a_range = set->contents_header.array[i].array[0];
- }
-
- // Index 6 is the salt.
- else if (f_compare_dynamic_partial_string(kt_tacocat_salt_s.string, set->buffer, kt_tacocat_salt_s.used, set->objects_header.array[i]) == F_equal_to) {
-
- // Require Content to exist.
- if (!set->contents_header.array[i].used) {
- set->abstruses.array[6].value.type = f_abstruse_none_e;
-
- continue;
- }
-
- set->abstruses.array[6].key = kt_tacocat_salt_s;
- set->abstruses.array[6].value.type = f_abstruse_range_e;
- set->abstruses.array[6].value.is.a_range = set->contents_header.array[i].array[0];
- }
- } // for
-
- // Convert the status code.
- if (set->abstruses.array[0].value.type) {
- const f_number_unsigned_t length = set->abstruses.array[0].value.is.a_range.stop - set->abstruses.array[0].value.is.a_range.start + 1;
- char buffer[length];
- f_status_t status = F_false;
-
- memcpy(buffer, set->buffer.string + set->abstruses.array[0].value.is.a_range.start, length);
-
- const f_string_static_t status_string = macro_f_string_static_t_initialize_1(buffer, 0, length);
-
- set->status = fl_status_string_from(status_string, &status);
-
- if (set->status == F_okay) {
- set->abstruses.array[0].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[0].value.is.a_unsigned = (f_number_unsigned_t) status;
- }
- else {
- kt_tacocat_print_error_on_packet_header_value_invalid(&main->program.error, kt_tacocat_receive_s, set->network, set->status, set->name, set->buffer, set->objects.array[at], set->abstruses.array[6].value.is.a_range);
-
- set->abstruses.array[0].value.type = f_abstruse_none_e;
- set->abstruses.array[0].value.is.a_unsigned = 0;
-
- set->status = F_status_set_error(F_packet);
- }
- }
-
- // Convert the type.
- if (set->abstruses.array[1].value.type) {
- if (f_compare_dynamic_partial_string(kt_tacocat_file_s.string, set->buffer, kt_tacocat_file_s.used, set->abstruses.array[1].value.is.a_range) == F_equal_to) {
- set->abstruses.array[1].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[1].value.is.a_unsigned = (f_number_unsigned_t) kt_tacocat_packet_type_file_e;
- }
- else if (f_compare_dynamic_partial_string(kt_tacocat_done_s.string, set->buffer, kt_tacocat_done_s.used, set->abstruses.array[1].value.is.a_range) == F_equal_to) {
- set->abstruses.array[1].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[1].value.is.a_unsigned = (f_number_unsigned_t) kt_tacocat_packet_type_done_e;
- }
- else if (f_compare_dynamic_partial_string(kt_tacocat_next_s.string, set->buffer, kt_tacocat_next_s.used, set->abstruses.array[1].value.is.a_range) == F_equal_to) {
- set->abstruses.array[1].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[1].value.is.a_unsigned = (f_number_unsigned_t) kt_tacocat_packet_type_next_e;
- }
- else if (f_compare_dynamic_partial_string(kt_tacocat_resend_s.string, set->buffer, kt_tacocat_resend_s.used, set->abstruses.array[1].value.is.a_range) == F_equal_to) {
- set->abstruses.array[1].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[1].value.is.a_unsigned = (f_number_unsigned_t) kt_tacocat_packet_type_resend_e;
- }
- else {
- set->status = F_status_set_error(F_found_not);
-
- kt_tacocat_print_error_on_packet_header_value_invalid(&main->program.error, kt_tacocat_receive_s, set->network, set->status, set->name, set->buffer, set->objects.array[at], set->abstruses.array[6].value.is.a_range);
-
- set->abstruses.array[1].value.type = f_abstruse_none_e;
- set->abstruses.array[1].value.is.a_unsigned = 0;
-
- set->status = F_status_set_error(F_packet);
-
- return;
- }
- }
-
- // Convert the length, part, and total.
- {
- f_number_unsigned_t number = 0;
-
- for (i = 2; i < 5; ++i) {
-
- if (!set->abstruses.array[i].value.type) continue;
-
- set->status = fl_conversion_dynamic_partial_to_unsigned(fl_conversion_data_base_10_c, set->buffer, set->abstruses.array[i].value.is.a_range, &number);
-
- if (set->status == F_okay) {
- set->abstruses.array[i].value.type = f_abstruse_unsigned_e;
- set->abstruses.array[i].value.is.a_unsigned = number;
- }
- else {
- kt_tacocat_print_error_on_packet_header_value_invalid(&main->program.error, kt_tacocat_receive_s, set->network, set->status, set->name, set->buffer, set->objects.array[at], set->abstruses.array[6].value.is.a_range);
-
- set->abstruses.array[i].value.type = f_abstruse_none_e;
- set->abstruses.array[i].value.is.a_unsigned = 0;
-
- set->status = F_status_set_error(F_packet);
- }
- } // for
- }
-
- set->abstruses.used = 6;
- set->status = F_okay;
- }
-#endif // _di_kt_tacocat_receive_process_extract_header_
-
-#ifndef _di_kt_tacocat_receive_process_extract_signature_
- void kt_tacocat_receive_process_extract_signature(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_number_unsigned_t at) {
-
- if (!main || !set) return;
-
- if (set->objects.array[at].start > set->objects.array[at].stop || !set->contents.array[at].used) {
- set->status = F_data_not;
-
- return;
- }
-
- set->range = set->contents.array[at].array[0];
-
- fll_fss_extended_read(set->buffer, &set->range, &set->objects_signature, &set->contents_signature, &set->objects_quoted_header, &set->contents_quoted_header, &set->objects_delimits_signature, &set->contents_delimits_signature, &set->state);
-
- if (F_status_is_error(set->state.status)) {
- kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(fll_fss_extended_read), kt_tacocat_receive_s, set->network, set->status, set->name);
-
- set->status = set->state.status;
-
- return;
- }
-
- // @todo maybe 7 and beyond in the abstruse shall represent signatures?
-
- set->status = F_okay;
+ set->abstruses.used = 0;
+ set->buffer.used = 0;
+ set->cache.used = 0;
+ set->header.used = 0;
+ set->headers.used = 0;
+ set->objects.used = 0;
+ set->contents.used = 0;
+ set->objects_delimits.used = 0;
+ set->contents_delimits.used = 0;
+ set->comments.used = 0;
+ set->retry = 0;
+ set->size_done = 0;
+ set->size_total = 0;
+ set->file.size_read = set->size_block;
+ set->socket.size_read = kt_tacocat_packet_read_d;
+ set->socket.id_data = -1;
+ set->range.start = 1;
+ set->range.stop = 0;
+ set->state.status = F_none;
+ set->status = F_none;
+ set->packet.control = 0;
+ set->packet.size = 0;
+ set->packet.payload.start = 1;
+ set->packet.payload.stop = 0;
+ set->part = 0;
+ set->parts.used = 0;
+ set->step = kt_tacocat_socket_step_receive_control_e;
+ set->flag = 0;
}
-#endif // _di_kt_tacocat_receive_process_extract_signature_
+#endif // _di_kt_tacocat_receive_process_initialize_
#ifdef __cplusplus
} // extern "C"
#endif // _di_kt_tacocat_receive_process_control_
/**
- * Process the header and signature strings, extracting the data.
- *
- * Another function should perform some of the validation on the header.
- * @todo This other function needs to return a status code such as F_continue to designate to continue to the next iteration.
- * Ideally, the flag will be set to how to continue, such as "continue loading the entire payload".
- * This situation would arise when the payload needs to be validated, such as the size.
- *
- * @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:
- * F_okay on success.
- *
- * Errors (with error bit) from: f_memory_array_increase_by().
- * Errors (with error bit) from: kt_tacocat_receive_process_extract_header().
- * Errors (with error bit) from: kt_tacocat_receive_process_extract_signature().
- *
- * @see f_memory_array_increase_by()
- * @see kt_tacocat_receive_process_extract_header()
- * @see kt_tacocat_receive_process_extract_signature()
- */
-#ifndef _di_kt_tacocat_receive_process_extract_
- extern void kt_tacocat_receive_process_extract(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
-#endif // _di_kt_tacocat_receive_process_extract_
-
-/**
- * Extract the header strings using the given index for an Object and Content.
- *
- * The positions in the abstruse are hard-coded with specific representations.
- *
- * Index Positions:
- * - 0: Status string (such as F_okay).
- * - 1: Type string (type of packet).
- * - 2: Length number (the length of the Payload section).
- * - 3: Packet part number.
- * - 4: Total packet parts number.
- * - 5: Name string (file name).
- * - 6: Salt string (for making packet unique, if encrypted, signed, or something similar).
- *
- * @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:
- * F_okay on success.
- * F_data_not on success, but no data to process.
- *
- * F_packet (with error bit) on invalid packet header.
- *
- * Errors (with error bit) from: fll_fss_extended_read().
- * @param at
- * The index position representing which Object and Contents set to use.
- *
- * @see fll_fss_extended_read()
- */
-#ifndef _di_kt_tacocat_receive_process_extract_header_
- extern void kt_tacocat_receive_process_extract_header(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_number_unsigned_t at);
-#endif // _di_kt_tacocat_receive_process_extract_header_
-
-/**
- * Extract the signature strings using the given index for an Object and Content.
+ * Process the network socket, performing the initialization step such as when step == 0.
*
* @param main
* The main program and settings data.
* The socket set to process.
* Must not be NULL.
*
- * This alters set.status:
- * F_okay on success.
- * @param at
- * The index position representing which Object and Contents set to use.
+ * This does not alter set.status.
*/
-#ifndef _di_kt_tacocat_receive_process_extract_signature_
- extern void kt_tacocat_receive_process_extract_signature(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set, const f_number_unsigned_t at);
-#endif // _di_kt_tacocat_receive_process_extract_signature_
+#ifndef _di_kt_tacocat_receive_process_initialize_
+ extern void kt_tacocat_receive_process_initialize(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_receive_process_initialize_
#ifdef __cplusplus
} // extern "C"
kt_tacocat_main_t * const main = (kt_tacocat_main_t *) void_main;
f_number_unsigned_t i = 0;
f_status_t ready = F_okay;
+ bool poll = F_false;
kt_tacocat_process_socket_set_send(main);
++main->setting.send.array[i].retry;
}
+ if (main->setting.send.array[i].step == kt_tacocat_socket_step_send_wait_e) {
+ poll = F_true;
+ }
+
ready = F_done_not;
}
}
} // for
+ if (F_status_is_error_not(main->setting.status_send) && poll) {
+ main->setting.status_send = f_file_poll(main->setting.send_polls, main->setting.active_send ? main->setting.interval_fast : main->setting.interval);
+
+ if (main->program.signal_received) {
+ main->setting.status_receive = F_status_set_error(F_interrupt);
+
+ return 0;
+ }
+
+ poll = F_false;
+ }
+
} while (F_status_is_error_not(main->setting.status_send) && ready == F_done_not);
}
if (!main || !set) return F_status_set_error(F_parameter);
if (!set->step) {
- set->abstruses.used = 0;
- set->buffer.used = 0;
- set->cache.used = 0;
- set->header.used = 0;
- set->headers.used = 0;
- set->objects.used = 0;
- set->contents.used = 0;
- set->objects_delimits.used = 0;
- set->contents_delimits.used = 0;
- set->comments.used = 0;
- set->retry = 0;
- set->size_done = 0;
- set->size_total = 0;
- set->file.size_read = set->size_block;
- set->socket.size_read = kt_tacocat_packet_read_d;
- set->range.start = -1;
- set->range.stop = 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;
-
- // Initialize the default file payload.
- set->status = f_memory_array_increase_by(kt_tacocat_packet_headers_d, sizeof(f_string_map_t), (void **) &set->headers.array, &set->headers.used, &set->headers.size);
-
- if (F_status_is_error_not(set->status)) {
- set->status = f_memory_array_increase_by(kt_tacocat_packet_prebuffer_d, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
- }
-
- if (F_status_is_error_not(set->status)) {
- kt_tacocat_process_abstruse_initialize(main, set);
- }
+ kt_tacocat_send_process_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->step);
+ macro_kt_send_process_handle_error_exit_1(main, kt_tacocat_send_process_initialize, kt_tacocat_send_s, set->network, set->status, set->name, set->step);
}
set->step = kt_tacocat_socket_step_send_size_e;
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 **) &.array, &.used, &.size);
+ 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.
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;
+ return F_done_not;
}
set->step = kt_tacocat_socket_step_send_build_e;
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->step);
+
+ set->status = state_local.status;
+
+ macro_kt_send_process_handle_error_exit_1(main, fl_fss_payload_header_map, kt_tacocat_send_build_s, set->network, set->status, set->name, set->step);
set->step = kt_tacocat_socket_step_send_header_e;
}
set->size_done += written;
+ set->status = F_okay;
+ set->step = kt_tacocat_socket_step_send_wait_e;
+
+ // 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_header_e;
+ set->step = kt_tacocat_socket_step_send_wait_e;
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)) {
}
#endif // _di_kt_tacocat_send_process_
+#ifndef _di_kt_tacocat_send_process_initialize_
+ void kt_tacocat_send_process_initialize(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) {
+
+ if (!main || !set) return;
+
+ set->abstruses.used = 0;
+ set->buffer.used = 0;
+ set->id.used = 0;
+ set->cache.used = 0;
+ set->header.used = 0;
+ set->headers.used = 0;
+ set->objects.used = 0;
+ set->contents.used = 0;
+ set->objects_delimits.used = 0;
+ set->contents_delimits.used = 0;
+ set->comments.used = 0;
+ set->retry = 0;
+ set->size_done = 0;
+ set->size_total = 0;
+ set->file.size_read = set->size_block;
+ set->socket.size_read = kt_tacocat_packet_read_d;
+ set->socket.id_data = -1;
+ set->range.start = 1;
+ set->range.stop = 0;
+ set->state.status = F_none;
+ set->status = F_none;
+ set->packet.control = 0;
+ set->packet.size = 0;
+ set->packet.payload.start = 1;
+ set->packet.payload.stop = 0;
+ set->part = 0;
+ set->parts.used = 0;
+ set->flag = 0;
+
+ // For writes, the id_data is the same as the id.
+ set->socket.id_data = set->socket.id;
+
+ // Initialize the default file payload.
+ set->status = f_memory_array_increase_by(kt_tacocat_packet_headers_d, sizeof(f_string_map_t), (void **) &set->headers.array, &set->headers.used, &set->headers.size);
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_memory_array_increase_by(kt_tacocat_packet_prebuffer_d, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ set->status = f_memory_array_increase_by(kt_tacocat_packet_id_length_d, sizeof(f_char_t), (void **) &set->id.string, &set->id.used, &set->id.size);
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ f_char_t id[kt_tacocat_packet_id_length_d];
+ f_string_static_t id_buffer = macro_f_string_static_t_initialize_2(id, 0);
+ uint8_t modded = 0;
+
+ memset(id, 0, kt_tacocat_packet_id_length_d);
+
+ if (F_status_is_error_not(f_random_read(0, kt_tacocat_packet_id_length_d, &id_buffer.string, &id_buffer.used))) {
+ for (uint8_t i = 0; i < id_buffer.used; i += macro_f_utf_byte_width(id[i])) {
+
+ if (f_utf_is_alphabetic_digit(id + i, kt_tacocat_packet_id_length_d - i, 0) == F_true) {
+ set->id.string[set->id.used++] = id[i];
+
+ if (macro_f_utf_byte_width(id[i]) > 1) {
+ set->id.string[set->id.used++] = id[i + 1];
+
+ if (macro_f_utf_byte_width(id[i]) > 2) {
+ set->id.string[set->id.used++] = id[i + 2];
+
+ if (macro_f_utf_byte_width(id[i]) > 3) {
+ set->id.string[set->id.used++] = id[i + 3];
+ }
+ }
+ }
+ }
+ else {
+ modded = ((uint8_t) id[i]) % 36;
+
+ // Fallback to ASCII based on current index position.
+ if (modded < 10) {
+ set->id.string[set->id.used++] = (modded) + 48;
+ }
+ else if (modded < 36) {
+ set->id.string[set->id.used++] = (modded) + 55; // ASCII 65 - 10 = 55.
+ }
+ else {
+ set->id.string[set->id.used++] = (modded) + 61; // ASCII 97 - 36 = 61.
+ }
+ }
+ } // for
+ }
+ else {
+ // @todo manually generate something, probably use the file name and the port number.
+ }
+ }
+
+ if (F_status_is_error_not(set->status)) {
+ kt_tacocat_process_abstruse_initialize(main, set);
+ }
+ }
+#endif // _di_kt_tacocat_send_process_initialize_
#ifdef __cplusplus
} // extern "C"
#endif
* F_payload_too_large (with error bit) on total payload size is too large.
* F_too_large (with error bit) on file too large.
*
+ * Errors (with error bit) from: kt_tacocat_process_abstruse_initialize()
+ *
* @return
- * F_done on success and done processing.
- * F_done_not on success but not done processing.
+ * F_done on success and done processing.
+ * F_done_not on success but not done processing.
*
- * F_parameter (with error bit) on invalid parameter.
+ * F_parameter (with error bit) on invalid parameter.
*
* @see f_socket_read_stream()
+ * @see kt_tacocat_send_process_initialize()
*/
#ifndef _di_kt_tacocat_send_process_
extern f_status_t kt_tacocat_send_process(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
#endif // _di_kt_tacocat_send_process_
+/**
+ * Process the network socket, performing the initialization step such as when step == 0.
+ *
+ * @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:
+ * 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.
+ * F_too_large (with error bit) on file too large.
+ *
+ * Errors (with error bit) from: f_memory_array_increase_by()
+ * Errors (with error bit) from: kt_tacocat_process_abstruse_initialize()
+ *
+ * @see f_memory_array_increase_by()
+ * @see kt_tacocat_process_abstruse_initialize()
+ */
+#ifndef _di_kt_tacocat_send_process_initialize_
+ extern void kt_tacocat_send_process_initialize(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set);
+#endif // _di_kt_tacocat_send_process_initialize_
+
#ifdef __cplusplus
} // extern "C"
#endif
#include <program/kevux/tools/tacocat/main/print/message.h>
#include <program/kevux/tools/tacocat/main/print/verbose.h>
#include <program/kevux/tools/tacocat/main/print/warning.h>
+#include <program/kevux/tools/tacocat/main/packet.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>