The port number should now be properly configurable (needed htons()).
Print a detailed error message for invalid ports.
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;
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.
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;
}
}
#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;
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;
}
}
*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 {
* - 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
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);
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);
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);
}
#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) {
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);
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);
#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