From 236c813c0e3ebbaedbc413c74565364031aa787c Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 1 Sep 2023 19:19:41 -0500 Subject: [PATCH] Progress: Further work in TacocaT, with a focus on setting up the port. The port number should now be properly configurable (needed htons()). Print a detailed error message for invalid ports. --- sources/c/tacocat/main/common.c | 55 +++++++++++++++++++++++------------- sources/c/tacocat/main/common.h | 5 +++- sources/c/tacocat/main/print/error.c | 32 +++++++++++++++++---- sources/c/tacocat/main/print/error.h | 24 ++++++++++++++++ 4 files changed, 91 insertions(+), 25 deletions(-) diff --git a/sources/c/tacocat/main/common.c b/sources/c/tacocat/main/common.c index 50d7434..cddf62f 100644 --- a/sources/c/tacocat/main/common.c +++ b/sources/c/tacocat/main/common.c @@ -351,6 +351,7 @@ extern "C" { port = 0; address = main->program.parameters.arguments.array[index]; f_char_t address_string[address.used]; + f_string_range_t port_range = f_string_range_t_initialize; memcpy(address_string, address.string, address.used); address.string = address_string; @@ -372,11 +373,25 @@ extern "C" { host.h_addrtype = 0; } - kt_tacocat_setting_load_address_port_extract(main, &address, &port); + kt_tacocat_setting_load_address_port_extract(main, &address, &port, &port_range); 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); + macro_setting_load_print_first(); + + if (port_range.start > port_range.stop) { + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(kt_tacocat_setting_load_address_port_extract)); + } + else { + kt_tacocat_print_error_port_number_invalid(&main->program.error, address, port_range); + } + + if (F_status_is_error_not(failed)) { + failed = main->setting.state.status; + } + + sets[i]->statuss.array[j] = main->setting.state.status; + + continue; } // Fail forward if port number is not supported by the system. @@ -473,12 +488,12 @@ extern "C" { if (host.h_addrtype == f_socket_address_family_inet4_e) { sets[i]->sockets.array[j].domain = f_socket_protocol_family_inet4_e; - sets[i]->sockets.array[j].address.inet4.sin_port = (in_port_t) port; + sets[i]->sockets.array[j].address.inet4.sin_port = htons((in_port_t) port); sets[i]->sockets.array[j].address.inet4.sin_addr.s_addr = INADDR_ANY; } else if (host.h_addrtype == f_socket_address_family_inet6_e) { sets[i]->sockets.array[j].domain = f_socket_protocol_family_inet6_e; - sets[i]->sockets.array[j].address.inet6.sin6_port = (in_port_t) port; + sets[i]->sockets.array[j].address.inet6.sin6_port = htons((in_port_t) port); sets[i]->sockets.array[j].address.inet6.sin6_addr = in6addr_any; } } @@ -635,11 +650,11 @@ extern "C" { #endif // _di_kt_tacocat_setting_load_send_receive_allocate_ #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) { + 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, f_string_range_t * const port_range) { if (!main) return; - if (!address || !port) { + if (!address || !port || !port_range) { main->setting.state.status = F_status_set_error(F_parameter); return; @@ -651,20 +666,22 @@ extern "C" { return; } - f_number_unsigned_t i = 0; + port_range->stop = address->used; if (main->setting.state.status == F_network_version_four || main->setting.state.status == F_network_version_six) { + port_range->start = 0; + if (*port) { - i = *port; + port_range->start = *port; *port = 0; - const f_string_static_t adjusted = macro_f_string_static_t_initialize_1(address->string + i, 0, address->used - i); + const f_string_static_t adjusted = macro_f_string_static_t_initialize_1(address->string + port_range->start, 0, address->used - port_range->start); 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; + address->string[port_range->start] = 0; + address->used = port_range->start; while (address->used && address->string[address->used] != f_string_ascii_colon_s.string[0]) --address->used; } @@ -675,20 +692,20 @@ extern "C" { } *port = 0; - i = address->used; + port_range->start = address->used; - while (--i) { - if (address->string[i] == f_string_ascii_colon_s.string[0]) break; + while (--port_range->start) { + if (address->string[port_range->start] == 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); + if (port_range->start && ++port_range->start < address->used) { + const f_string_static_t adjusted = macro_f_string_static_t_initialize_1(address->string + port_range->start, 0, address->used - port_range->start); 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; + address->string[--port_range->start] = 0; + address->used = port_range->start; main->setting.state.status = F_okay; } else { diff --git a/sources/c/tacocat/main/common.h b/sources/c/tacocat/main/common.h index 3eab593..49af87c 100644 --- a/sources/c/tacocat/main/common.h +++ b/sources/c/tacocat/main/common.h @@ -147,13 +147,16 @@ extern "C" { * - Decimal (base 10) is used for all other cases. * @param port * The extracted port number. + * @param port_range + * The range in the string representing the extracted port number. + * This is primarily intended for printing errors. * * 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); + 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, f_string_range_t * const port_range); #endif // _di_kt_tacocat_setting_load_address_port_extract_ #ifdef __cplusplus diff --git a/sources/c/tacocat/main/print/error.c b/sources/c/tacocat/main/print/error.c index 6b7f8f1..595fe9f 100644 --- a/sources/c/tacocat/main/print/error.c +++ b/sources/c/tacocat/main/print/error.c @@ -40,7 +40,7 @@ extern "C" { fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable); fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s); fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable); - fl_print_format(" %['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); + fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); f_file_stream_unlock(print->to); @@ -62,7 +62,7 @@ extern "C" { fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable); fl_print_format(" %[buffer for '%]", print->to, print->set->error, print->set->error, f_string_eol_s); fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable); - fl_print_format(" %['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); + fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); f_file_stream_unlock(print->to); @@ -86,7 +86,7 @@ extern "C" { fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, kt_tacocat_kevux_s, print->set->notable); fl_print_format(" %[' but '%]", 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, unknown, print->set->notable); - fl_print_format(" %[' is given.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); + fl_print_format("%[' is given.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); f_file_stream_unlock(print->to); @@ -94,6 +94,28 @@ extern "C" { } #endif // _di_kt_tacocat_print_error_parameter_value_resolve_unknown_ +#ifndef _di_kt_tacocat_print_error_port_number_invalid_ + f_status_t kt_tacocat_print_error_port_number_invalid(fl_print_t * const print, const f_string_static_t address, const f_string_range_t port_range) { + + if (!print || !print->custom) return F_status_set_error(F_output_not); + if (print->verbosity < f_console_verbosity_error_e) return F_output_not; + + kt_tacocat_main_t * const main = (kt_tacocat_main_t *) print->custom; + + 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, port_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); + + f_file_stream_unlock(print->to); + + return F_okay; + } +#endif // _di_kt_tacocat_print_error_port_number_invalid_ + #ifndef _di_kt_tacocat_print_error_setting_socket_lengths_must_match_ f_status_t kt_tacocat_print_error_setting_socket_lengths_must_match(fl_print_t * const print, const f_string_dynamic_t name, const kt_tacocat_socket_set_t set) { @@ -114,7 +136,7 @@ extern "C" { fl_print_format("%[%ul%]", print->to, print->set->notable, set.sockets.used, print->set->notable); fl_print_format(" %[', and the status array length is '%]", print->to, print->set->error, print->set->error, f_string_eol_s); fl_print_format("%[%ul%]", print->to, print->set->notable, set.statuss.used, print->set->notable); - fl_print_format(" %['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); + fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); f_file_stream_unlock(print->to); @@ -134,7 +156,7 @@ extern "C" { fl_print_format("%[%ul%]", print->to, print->set->notable, protocol, print->set->notable); fl_print_format(" %[while processing '%]", print->to, print->set->error, print->set->error, f_string_eol_s); fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable); - fl_print_format(" %['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); + fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); f_file_stream_unlock(print->to); diff --git a/sources/c/tacocat/main/print/error.h b/sources/c/tacocat/main/print/error.h index a2d8253..18f3613 100644 --- a/sources/c/tacocat/main/print/error.h +++ b/sources/c/tacocat/main/print/error.h @@ -141,6 +141,30 @@ extern "C" { #endif // _di_kt_tacocat_print_error_parameter_value_resolve_unknown_ /** + * Print error about invalid port number in address. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + * @param address + * The entire address string, including the port number. + * @param port_range + * The range within the address string representing the port. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + * + * @see fll_error_file_print() + */ +#ifndef _di_kt_tacocat_print_error_port_number_invalid_ + extern f_status_t kt_tacocat_print_error_port_number_invalid(fl_print_t * const print, const f_string_static_t address, const f_string_range_t port_range); +#endif // _di_kt_tacocat_print_error_port_number_invalid_ + +/** * Print error message for when an the different socket relating structure arrays do not have the same length. * * @param print -- 1.8.3.1