From: Kevin Day Date: Sun, 9 Jul 2023 16:36:00 +0000 (-0500) Subject: Progress: Further work in TacocaT. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=673d20b7b19de1226bd6be0aac702071b6f52a10;p=kevux-tools Progress: Further work in TacocaT. Of note, this changes IP address and port extraction processing logic. --- diff --git a/data/build/tacocat/dependencies b/data/build/tacocat/dependencies index a583830..8b9bf31 100644 --- a/data/build/tacocat/dependencies +++ b/data/build/tacocat/dependencies @@ -9,6 +9,7 @@ f_utf f_color f_console f_compare +f_conversion f_file f_network f_path @@ -18,6 +19,7 @@ f_signal f_socket f_thread +fl_conversion fl_print fll_error diff --git a/data/build/tacocat/settings b/data/build/tacocat/settings index 154bf09..3e234b7 100644 --- a/data/build/tacocat/settings +++ b/data/build/tacocat/settings @@ -32,7 +32,7 @@ build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_print -lf_color -lf_compare -lf_console -lf_file -lf_memory -lf_network -lf_path -lf_pipe -lf_print -lf_signal -lf_socket -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_conversion -lfl_print -lf_color -lf_compare -lf_console -lf_conversion -lf_file -lf_memory -lf_network -lf_path -lf_pipe -lf_print -lf_signal -lf_socket -lf_string -lf_type_array -lf_utf build_libraries-individual_thread -lf_thread build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll diff --git a/sources/c/tacocat/main/common.c b/sources/c/tacocat/main/common.c index 60ae83f..8083e09 100644 --- a/sources/c/tacocat/main/common.c +++ b/sources/c/tacocat/main/common.c @@ -167,11 +167,6 @@ extern "C" { kt_tacocat_long_send_s, }; - f_string_dynamics_t * const strings[] = { - &main->setting.receives, - &main->setting.sends, - }; - f_files_t * const files[] = { &main->setting.file_receives, &main->setting.file_sends, @@ -187,6 +182,11 @@ extern "C" { &main->setting.status_sends, }; + f_string_dynamics_t * const strings[] = { + &main->setting.receives, + &main->setting.sends, + }; + const bool const is_receive[] = { F_true, F_false, @@ -199,6 +199,8 @@ extern "C" { f_status_t failed = F_none; struct hostent host; f_network_family_ip_t family = f_network_family_ip_t_initialize; + f_number_unsigned_t port = 0; + f_string_static_t address = f_string_static_t_initialize; for (uint8_t i = 0; i < 2; ++i) { @@ -223,37 +225,37 @@ extern "C" { main->setting.state.status = f_string_dynamics_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, strings[i]); - macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamics_increase_by); + macro_setting_load_handle_send_receive_error_continue_1(f_string_dynamics_increase_by); main->setting.state.status = f_files_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, files[i]); - macro_setting_load_handle_send_receive_error_continue_basic(f_files_increase_by); + macro_setting_load_handle_send_receive_error_continue_1(f_files_increase_by); main->setting.state.status = f_sockets_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, sockets[i]); - macro_setting_load_handle_send_receive_error_continue_basic(f_sockets_increase_by); + macro_setting_load_handle_send_receive_error_continue_1(f_sockets_increase_by); main->setting.state.status = f_statuss_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, statuss[i]); - macro_setting_load_handle_send_receive_error_continue_basic(f_statuss_increase_by); + macro_setting_load_handle_send_receive_error_continue_1(f_statuss_increase_by); for (j = 0; j < main->program.parameters.array[parameters[i]].values.used; j += 2) { // First parameter value represents the network address or the socket file path. index = main->program.parameters.array[parameters[i]].values.array[j]; + statuss[i]->array[j] = F_none; strings[i]->array[j].used = 0; if (main->program.parameters.arguments.array[index].used) { if (f_path_is_absolute(main->program.parameters.arguments.array[index]) == F_true || f_path_is_relative_current(main->program.parameters.arguments.array[index]) == F_true) { - // Two is added to support a trailing NULL and a type character. main->setting.state.status = f_string_dynamic_increase_by(main->program.parameters.arguments.array[index].used + 2, &strings[i]->array[j]); - macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_increase_by); + macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_increase_by); main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &strings[i]->array[j]); - macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_append_nulless); + macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append_nulless); // Designate this as a socket file by appending after the terminating NULL, past the used length. strings[i]->array[j].string[strings[i]->array[j].used] = 0; @@ -262,7 +264,7 @@ extern "C" { if (is_receive[i]) { main->setting.state.status = f_file_exists(strings[i]->array[j], F_true); - macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_append_nulless); + macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append_nulless); } strings[i]->array[j].string[strings[i]->array[j].used] = 0; @@ -274,90 +276,148 @@ extern "C" { else if (main->setting.flag & kt_tacocat_main_flag_resolve_classic_e) { memset(&host, 0, sizeof(struct hostent)); - main->setting.state.status = f_network_from_ip_name(main->program.parameters.arguments.array[index], &host); - - // @todo provide network-specific error messages. - macro_setting_load_handle_send_receive_error_continue_basic(f_network_from_ip_name); + port = 0; + address = main->program.parameters.arguments.array[index]; + f_char_t address_string[address.used]; - if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) { - macro_setting_load_print_first(); + memcpy(address_string, address.string, address.used); + address.string = address_string; - // @todo provide network-specific error messages for when no hosts are returned. - kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_network_from_ip_name)); + f_network_is_ip_address(address, &port, &main->setting.state); - if (F_status_is_error_not(failed)) { - failed = main->setting.state.status; - } + if (F_status_is_error(main->setting.state.status)) { + // @todo print error message about bad port number or similar. + macro_setting_load_handle_send_receive_error_continue_2(f_network_is_ip_address); + } - continue; + if (main->setting.state.status == F_network_version_four) { + host.h_addrtype = f_socket_address_family_inet4_e; + } + else if (main->setting.state.status == F_network_version_six) { + host.h_addrtype = f_socket_address_family_inet6_e; + } + else { + host.h_addrtype = 0; } - // Two is added to support a trailing NULL and a type character. - main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 1, &strings[i]->array[j]); + kt_tacocat_setting_load_address_port_extract(main, &address, &port); - macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_increase_by); + if (F_status_is_error(main->setting.state.status)) { + // @todo print error message about bad port number or similar. + macro_setting_load_handle_send_receive_error_continue_2(kt_tacocat_setting_load_address_port_extract); + } - // Randomly select one of the addresses when there are more than one. - if (host.h_addr_list[1]) { - k = 2; + // Fail forward if port number is not supported by the system. + if (port != (in_port_t) port) { + kt_tacocat_print_warning_port_number_overflow(&main->program.warning, main->program.parameters.arguments.array[index], port); - while (host.h_addr_list[k++]); + port = 0; + } + + if (host.h_addrtype) { + main->setting.state.status = f_string_dynamic_append(address, &strings[i]->array[j]); - // Real randomness or security is not needed here, so fiddle with predictable but somewhat dynamic numbers. - srand(main->program.pid + j + host.h_addr_list[0][0]); - k = rand() % (k - 1); + macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_append); } else { - k = 0; - } + // @todo move this block into its own function. + main->setting.state.status = f_network_from_ip_name(address, &host); - // Two is added to support a trailing NULL and a type character. - main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 1, &strings[i]->array[j]); + // @todo provide network-specific error messages. + macro_setting_load_handle_send_receive_error_continue_2(f_network_from_ip_name); - macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_increase_by); + if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) { + main->setting.state.status = F_status_set_error(F_parameter); - if (host.h_addrtype == f_socket_address_family_inet4_e) { - family.type = f_network_family_ip_4_e; - family.address.v4 = *((struct in_addr *) host.h_addr_list[k]); - } - else { - family.type = f_network_family_ip_6_e; - family.address.v6 = *((struct in6_addr *) host.h_addr_list[k]); - } + macro_setting_load_print_first(); + + // @todo provide network-specific error messages for when no hosts are returned. + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_network_from_ip_name)); + + if (F_status_is_error_not(failed)) { + failed = main->setting.state.status; + } + + statuss[i]->array[j] = main->setting.state.status; + + continue; + } + + main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 1, &strings[i]->array[j]); + + macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_increase_by); + + // Randomly select one of the addresses when there are more than one. + if (host.h_addr_list[1]) { + k = 2; + + while (host.h_addr_list[k++]); + + // Real randomness or security is not needed here, so fiddle with predictable but somewhat dynamic numbers. + srand(main->program.pid + j + host.h_addr_list[0][0]); + k = rand() % (k - 1); + } + else { + k = 0; + } + + main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 1, &strings[i]->array[j]); + + macro_setting_load_handle_send_receive_error_continue_2(f_string_dynamic_increase_by); + + if (host.h_addrtype == f_socket_address_family_inet4_e) { + family.type = f_network_family_ip_4_e; + family.address.v4 = *((struct in_addr *) host.h_addr_list[k]); + } + else { + family.type = f_network_family_ip_6_e; + family.address.v6 = *((struct in6_addr *) host.h_addr_list[k]); + } + + main->setting.state.status = f_network_to_ip_string(family, &strings[i]->array[j]); + + if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) { + main->setting.state.status = F_status_set_error(F_parameter); + + macro_setting_load_print_first(); - main->setting.state.status = f_network_to_ip_string(family, &strings[i]->array[j]); + // @todo provide network-specific error messages for when no hosts are returned. + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_network_from_ip_name)); - if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) { - macro_setting_load_print_first(); + if (F_status_is_error_not(failed)) { + failed = main->setting.state.status; + } - // @todo provide network-specific error messages for when no hosts are returned. - kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_network_from_ip_name)); + statuss[i]->array[j] = main->setting.state.status; - if (F_status_is_error_not(failed)) { - failed = main->setting.state.status; + continue; } - continue; + strings[i]->array[j].string[strings[i]->array[j].used] = 0; } - strings[i]->array[j].string[strings[i]->array[j].used] = 0; sockets[i]->array[j].protocol = f_socket_protocol_tcp_e; sockets[i]->array[j].type = host.h_addrtype; if (host.h_addrtype == f_socket_address_family_inet4_e) { sockets[i]->array[j].domain = f_socket_protocol_family_inet4_e; - sockets[i]->array[j].address.inet4.sin_port = 0; // @todo detect and pull port number from host name if supplied. + sockets[i]->array[j].address.inet4.sin_port = (in_port_t) port; sockets[i]->array[j].address.inet4.sin_addr.s_addr = INADDR_ANY; } else if (host.h_addrtype == f_socket_address_family_inet6_e) { sockets[i]->array[j].domain = f_socket_protocol_family_inet6_e; - sockets[i]->array[j].address.inet6.sin6_port = 0; // @todo detect and pull port number from host name if supplied. + sockets[i]->array[j].address.inet6.sin6_port = (in_port_t) port; sockets[i]->array[j].address.inet6.sin6_addr = in6addr_any; } } else { // @todo Kevux DNS resolution. } + + ++files[i]->used; + ++sockets[i]->used; + ++statuss[i]->used; + ++strings[i]->used; } else { main->setting.state.status = F_status_set_error(F_parameter); @@ -370,6 +430,8 @@ extern "C" { failed = main->setting.state.status; } + statuss[i]->array[j] = main->setting.state.status; + continue; } @@ -379,26 +441,29 @@ extern "C" { if (main->program.parameters.arguments.array[index].used) { // Make sure the current file is closed. - f_file_close(&files[i]->array[files[i]->used]); + f_file_close(&files[i]->array[j]); if (is_receive[i]) { - files[i]->array[files[i]->used].flag = F_file_flag_append_wo_d; - files[i]->array[files[i]->used].size_read = main->setting.block_size_send; - files[i]->array[files[i]->used].size_write = main->setting.block_size_send; + files[i]->array[j].flag = F_file_flag_append_wo_d; + files[i]->array[j].size_read = main->setting.block_size_send; + files[i]->array[j].size_write = main->setting.block_size_send; } else { - files[i]->array[files[i]->used].flag = F_file_flag_read_only_d; - files[i]->array[files[i]->used].size_read = main->setting.block_size_receive; - files[i]->array[files[i]->used].size_write = main->setting.block_size_receive; + files[i]->array[j].flag = F_file_flag_read_only_d; + files[i]->array[j].size_read = main->setting.block_size_receive; + files[i]->array[j].size_write = main->setting.block_size_receive; } - main->setting.state.status = f_file_open(main->program.parameters.arguments.array[index], F_file_mode_all_rw_d, &files[i]->array[files[i]->used]); + main->setting.state.status = f_file_open(main->program.parameters.arguments.array[index], F_file_mode_all_rw_d, &files[i]->array[j]); if (F_status_is_error(main->setting.state.status)) { - macro_setting_load_handle_send_receive_error_file_continue_basic(f_file_open, main->program.parameters.arguments.array[index], f_file_operation_open_s, fll_error_file_type_file_e); - } - else { - ++files[i]->used; + macro_setting_load_handle_send_receive_error_file_continue_1(f_file_open, main->program.parameters.arguments.array[index], f_file_operation_open_s, fll_error_file_type_file_e); + + if (F_status_is_error_not(failed)) { + failed = main->setting.state.status; + } + + statuss[i]->array[j] = main->setting.state.status; } } else { @@ -412,6 +477,8 @@ extern "C" { failed = main->setting.state.status; } + statuss[i]->array[j] = main->setting.state.status; + continue; } } // for @@ -435,7 +502,70 @@ extern "C" { main->setting.state.status = failed; } } -#endif // _di_kt_tacocat_setting_load_ +#endif // _di_kt_tacocat_setting_load_send_receive_ + +#ifndef _di_kt_tacocat_setting_load_address_port_extract_ + void kt_tacocat_setting_load_address_port_extract(kt_tacocat_main_t * const main, f_string_static_t * const address, f_number_unsigned_t * const port) { + + if (!main) return; + + if (!address || !port) { + main->setting.state.status = F_status_set_error(F_parameter); + + return; + } + + if (!address->used) { + main->setting.state.status = F_data_not; + + return; + } + + f_number_unsigned_t i = 0; + + if (main->setting.state.status == F_network_version_four || main->setting.state.status == F_network_version_six) { + if (*port) { + i = *port; + *port = 0; + + const f_string_static_t adjusted = macro_f_string_static_t_initialize_1(address->string + i, 0, address->used - i); + + main->setting.state.status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, adjusted, port); + if (F_status_is_error(main->setting.state.status)) return; + + address->string[i] = 0; + address->used = i; + + while (address->used && address->string[address->used] != f_string_ascii_colon_s.string[0]) --address->used; + } + + main->setting.state.status = F_none; + + return; + } + + *port = 0; + i = address->used; + + while (--i) { + if (address->string[i] == f_string_ascii_colon_s.string[0]) break; + } // while + + if (i && i + 1 < address->used) { + const f_string_static_t adjusted = macro_f_string_static_t_initialize_1(address->string + i + 1, 0, address->used - i - 1); + + main->setting.state.status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, adjusted, port); + if (F_status_is_error(main->setting.state.status)) return; + + address->string[i] = 0; + address->used = i; + main->setting.state.status = F_none; + } + else { + main->setting.state.status = F_number_not; + } + } +#endif // _di_kt_tacocat_setting_load_address_port_extract_ #ifdef __cplusplus } // extern "C" diff --git a/sources/c/tacocat/main/common.h b/sources/c/tacocat/main/common.h index 513254e..5f265cd 100644 --- a/sources/c/tacocat/main/common.h +++ b/sources/c/tacocat/main/common.h @@ -67,7 +67,7 @@ extern "C" { * * This must be of type kt_tacocat_main_t. * - * This alters setting.status: + * This alters main.setting.state.status: * F_none on success. * * F_parameter (with error bit) on parameter error. @@ -94,6 +94,49 @@ extern "C" { extern void kt_tacocat_setting_load_send_receive(const f_console_arguments_t arguments, void * const main); #endif // _di_kt_tacocat_setting_load_send_receive_ +/** + * Process the string and extract any potential port numbers. + * + * A port number is expected to be a digit following the last ':' at the end of the string. + * + * This does not print error messages. + * + * @param main + * The main program and settings data. + * + * The main.setting.state.status can be set to either F_network_version_four or F_network_version_six when calling this function to bypass IP type detection. + * + * This alters main.setting.state.status: + * F_none on success. + * F_data_not on success but there is nothing in the address string (address.used is 0). + * F_number_not on success but there is no port number. + * + * F_parameter (with error bit) on parameter error. + * + * Errors (with error bit) from: fl_conversion_dynamic_to_unsigned_detect(). + * @param address + * The string representing the address to extract the port number from. + * If a valid number is found, then this is updated to truncate the length at the colon and a NULL termination is inserted at the colon. + * For IPv6, only bracket wrapped addresses are supported when using port number (like [2001:db8::1]:80). + * Base notations for port numbers are supported (such as specifying hexidecimal like [2001:db8::1]:0x50 or specifying octal like 127.0.0.1:0o120) + * + * Supported base notations: + * - Hexidecimals (base 16) begin with either '0x' or '0X'. + * - Duodecimals (base 12) begin with either '0d' or '0D'. + * - Octals (base 8) begin with either '0o' or '0O'. + * - Binaries (base 2) begin with either '0b' or '0B'. + * - Decimal (base 10) is used for all other cases. + * @param port + * The extracted port number. + * + * When main.setting.state.status is set to either F_network_version_four or F_network_version_six when calling this function, the port represents the location within the address string that the port number begins. + * + * @see fl_conversion_dynamic_to_unsigned_detect() + */ +#ifndef _di_kt_tacocat_setting_load_address_port_extract_ + extern void kt_tacocat_setting_load_address_port_extract(kt_tacocat_main_t * const main, f_string_static_t * const address, f_number_unsigned_t * const port); +#endif // _di_kt_tacocat_setting_load_address_port_extract_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sources/c/tacocat/main/common/define.h b/sources/c/tacocat/main/common/define.h index 5fafccb..2d8922a 100644 --- a/sources/c/tacocat/main/common/define.h +++ b/sources/c/tacocat/main/common/define.h @@ -55,12 +55,12 @@ extern "C" { * macro_setting_load_print_first: * Intended to be used to simplify the code in kt_tacocat_setting_load() and make it more readable. * - * macro_setting_load_handle_send_receive_error_continue_basic: + * macro_setting_load_handle_send_receive_error_continue_1: * Intended to be used to simplify the code in kt_tacocat_setting_load_send_receive() and make it more readable. * This is for the basic error that calls kt_tacocat_print_error() when printing. * - * macro_setting_load_handle_send_receive_error_file_continue_basic: - * The same as macro_setting_load_handle_send_receive_error_continue_basic() but intended for file errors. + * macro_setting_load_handle_send_receive_error_file_continue_1: + * The same as macro_setting_load_handle_send_receive_error_continue_1() but intended for file errors. */ #ifndef _di_kt_tacocat_macros_d_ #define macro_setting_load_print_first() \ @@ -68,7 +68,7 @@ extern "C" { fll_print_dynamic_raw(f_string_eol_s, main->program.message.to); \ } - #define macro_setting_load_handle_send_receive_error_continue_basic(method) \ + #define macro_setting_load_handle_send_receive_error_continue_1(method) \ if (F_status_is_error(main->setting.state.status)) { \ macro_setting_load_print_first(); \ \ @@ -81,7 +81,22 @@ extern "C" { continue; \ } - #define macro_setting_load_handle_send_receive_error_file_continue_basic(method, name, operation, type) \ + #define macro_setting_load_handle_send_receive_error_continue_2(method) \ + if (F_status_is_error(main->setting.state.status)) { \ + macro_setting_load_print_first(); \ + \ + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(method)); \ + \ + if (F_status_is_error_not(failed)) { \ + failed = main->setting.state.status; \ + } \ + \ + statuss[i]->array[j] = main->setting.state.status; \ + \ + continue; \ + } + + #define macro_setting_load_handle_send_receive_error_file_continue_1(method, name, operation, type) \ if (F_status_is_error(main->setting.state.status)) { \ macro_setting_load_print_first(); \ \ @@ -91,6 +106,8 @@ extern "C" { failed = main->setting.state.status; \ } \ \ + statuss[i]->array[j] = main->setting.state.status; \ + \ continue; \ } #endif // _di_kt_tacocat_macro_d_ diff --git a/sources/c/tacocat/main/common/print.c b/sources/c/tacocat/main/common/print.c index 94f0aed..1036b71 100644 --- a/sources/c/tacocat/main/common/print.c +++ b/sources/c/tacocat/main/common/print.c @@ -10,6 +10,7 @@ extern "C" { "f_file_open", "f_files_increase_by", "f_network_from_ip_name", + "f_network_is_ip_address", "f_socket_bind_inet4", "f_socket_bind_inet6", "f_socket_bind_local", @@ -20,12 +21,14 @@ extern "C" { "f_sockets_increase_by", "f_statuss_increase_by", "f_string_append_nulless", + "f_string_dynamic_append", "f_string_dynamic_append_nulless", "f_string_dynamic_increase_by", "f_string_dynamics_increase_by", "f_thread_create", "fll_program_parameter_process_context", "fll_program_parameter_process_verbosity", + "kt_tacocat_setting_load_address_port_extract", }; #endif // _di_kt_tacocat_f_a_ diff --git a/sources/c/tacocat/main/common/print.h b/sources/c/tacocat/main/common/print.h index 36235ed..a0fb409 100644 --- a/sources/c/tacocat/main/common/print.h +++ b/sources/c/tacocat/main/common/print.h @@ -43,6 +43,7 @@ extern "C" { kt_tacocat_f_f_file_open_e, kt_tacocat_f_f_files_increase_by_e, kt_tacocat_f_f_network_from_ip_name_e, + kt_tacocat_f_f_network_is_ip_address_e, kt_tacocat_f_f_socket_bind_inet4_e, kt_tacocat_f_f_socket_bind_inet6_e, kt_tacocat_f_f_socket_bind_local_e, @@ -53,12 +54,14 @@ extern "C" { kt_tacocat_f_f_sockets_increase_by_e, kt_tacocat_f_f_statuss_increase_by_e, kt_tacocat_f_f_string_append_nulless_e, + kt_tacocat_f_f_string_dynamic_append_e, kt_tacocat_f_f_string_dynamic_append_nulless_e, kt_tacocat_f_f_string_dynamic_increase_by_e, kt_tacocat_f_f_string_dynamics_increase_by_e, kt_tacocat_f_f_thread_create_e, kt_tacocat_f_fll_program_parameter_process_context_e, kt_tacocat_f_fll_program_parameter_process_verbosity_e, + kt_tacocat_f_kt_tacocat_setting_load_address_port_extract_e, }; // enum #endif // _di_kt_tacocat_f_e_ diff --git a/sources/c/tacocat/main/print/warning.c b/sources/c/tacocat/main/print/warning.c index 87f1956..e8207e3 100644 --- a/sources/c/tacocat/main/print/warning.c +++ b/sources/c/tacocat/main/print/warning.c @@ -4,6 +4,25 @@ extern "C" { #endif +#ifndef _di_fake_build_print_warning_setting_boolean_may_only_be_ + f_status_t kt_tacocat_print_warning_port_number_overflow(fl_print_t * const print, const f_string_static_t address, const f_number_unsigned_t port) { + + if (print->verbosity < f_console_verbosity_verbose_e) return F_output_not; + + f_file_stream_lock(print->to); + + fl_print_format("%[%QThe port number '%]", print->to, print->context, print->prefix, print->context); + fl_print_format("%[%ul%]", print->to, print->notable, port, print->notable); + fl_print_format("%[' from the address '%]", print->to, print->context, print->context); + fl_print_format("%[%Q%]", print->to, print->notable, address, print->notable); + fl_print_format("%['is too large for this system and so the port is being autodetermined.%]%r", print->to, print->context, print->context, f_string_eol_s); + + f_file_stream_unlock(print->to); + + return F_none; + } +#endif // _di_fake_build_print_warning_setting_boolean_may_only_be_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sources/c/tacocat/main/print/warning.h b/sources/c/tacocat/main/print/warning.h index 7cd756b..b6d40f0 100644 --- a/sources/c/tacocat/main/print/warning.h +++ b/sources/c/tacocat/main/print/warning.h @@ -16,6 +16,34 @@ extern "C" { #endif +/** + * Print warning message about given port number being out of range for this system. + * + * @param print + * The output structure to print to. + * + * This requires print.custom to be fake_main_t. + * + * This does not alter print.custom.setting.state.status. + * @param address + * The original address string. + * @param port + * The out of range port. + * + * @return + * F_none on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + * + * @see f_file_stream_lock() + * @see f_file_stream_unlock() + * @see fl_print_format() + */ +#ifndef _di_kt_tacocat_print_warning_port_number_overflow_ + extern f_status_t kt_tacocat_print_warning_port_number_overflow(fl_print_t * const print, const f_string_static_t address, const f_number_unsigned_t port); +#endif // _di_kt_tacocat_print_warning_port_number_overflow_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sources/c/tacocat/main/process.c b/sources/c/tacocat/main/process.c index a2dd618..8e87ada 100644 --- a/sources/c/tacocat/main/process.c +++ b/sources/c/tacocat/main/process.c @@ -34,6 +34,7 @@ extern "C" { for (; i < main->setting.socket_receives.used; ++i) { if (kt_tacocat_signal_check(main)) return; + if (F_status_is_error(main->setting.status_receives.array[i])) continue; main->setting.status_receives.array[i] = f_socket_create(&main->setting.socket_receives.array[i]); @@ -85,6 +86,7 @@ extern "C" { for (i = 0; i < main->setting.socket_sends.used; ++i) { if (kt_tacocat_signal_check(main)) return; + if (F_status_is_error(main->setting.status_sends.array[i])) continue; // @todo check to see if connection is one of "local", "inet" (ipv4), or "inet6" (ipv6) and configure socket appropriately. diff --git a/sources/c/tacocat/main/signal.h b/sources/c/tacocat/main/signal.h index bc5f375..e44651f 100644 --- a/sources/c/tacocat/main/signal.h +++ b/sources/c/tacocat/main/signal.h @@ -63,7 +63,7 @@ extern "C" { * * This alters main.program.signal_received, setting it to a received signal. * - * This alters setting.status: + * This alters main.setting.state.status: * Errors (with error bit) from: f_signal_open() * Errors (with error bit) from: f_signal_wait() * diff --git a/sources/c/tacocat/main/tacocat.h b/sources/c/tacocat/main/tacocat.h index 92c32be..f0c837c 100644 --- a/sources/c/tacocat/main/tacocat.h +++ b/sources/c/tacocat/main/tacocat.h @@ -37,6 +37,7 @@ #include // FLL-1 includes. +#include #include // FLL-2 includes.