I decided to keep things simple and remove the background process and PID file related functionality.
I renamed "from" and "to" into "receive" and "send".
This relating context makes more sense and can be less confusing.
The network and the local files should be just about ready to use.
The actual implementation of the network processing code is next.
I intend to use either threading or forking to handle each send or receive connection set.
# fss-0000
_di_thread_support_ Disable thread support, handling signals without using a separate thread.
+_kt_resolve_default_kevux_ Default to Kevux DNS resolution methods rather than classic DNS resolution methods.
f_utf
f_color
f_console
+f_compare
+f_file
f_network
f_path
f_pipe
build_language c
build_libraries -lc
-build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_print -lf_color -lf_console -lf_memory -lf_network -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf
+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_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
-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/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/process.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/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/process.h main/signal.h main/tacocat.h main/thread.h
build_sources_program main/main.c
}
}
+ f_number_unsigned_t index = 0;
+
if (main->program.parameters.array[kt_tacocat_parameter_help_e].result & f_console_result_found_e) {
main->setting.flag |= kt_tacocat_main_flag_help_e;
}
main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_copyright_e;
}
- if (main->program.parameters.array[kt_tacocat_parameter_background_e].result & f_console_result_found_e) {
- main->setting.flag |= kt_tacocat_main_flag_background_e;
- }
- else {
- main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_background_e;
+ if (main->program.parameters.array[kt_tacocat_parameter_resolve_e].result & f_console_result_found_e) {
+ main->setting.state.status = F_status_set_error(F_parameter);
+
+ macro_setting_load_print_first();
+
+ fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, kt_tacocat_long_resolve_s);
}
+ else if (main->program.parameters.array[kt_tacocat_parameter_resolve_e].result & f_console_result_value_e) {
+ index = main->program.parameters.array[kt_tacocat_parameter_resolve_e].values.array[main->program.parameters.array[kt_tacocat_parameter_resolve_e].values.used - 1];
- if (main->program.parameters.array[kt_tacocat_parameter_pid_e].result & f_console_result_found_e) {
- main->setting.flag |= kt_tacocat_main_flag_pid_e;
+ if (f_compare_dynamic(main->program.parameters.arguments.array[index], kt_tacocat_classic_s) == F_equal_to) {
+ main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_resolve_kevux_e;
+ main->setting.flag |= kt_tacocat_main_flag_resolve_classic_e;
+ }
+ else if (f_compare_dynamic(main->program.parameters.arguments.array[index], kt_tacocat_kevux_s) == F_equal_to) {
+ main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_resolve_classic_e;
+ main->setting.flag |= kt_tacocat_main_flag_resolve_kevux_e;
+ }
+ else {
+ main->setting.state.status = F_status_set_error(F_parameter);
+
+ macro_setting_load_print_first();
+
+ kt_tacocat_print_error_parameter_value_resolve_unknown(&main->program.error, main->program.parameters.arguments.array[index]);
+ }
}
else {
- main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_pid_e;
+ #ifdef _kt_resolve_default_kevux_
+ main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_resolve_classic_e;
+ main->setting.flag |= kt_tacocat_main_flag_resolve_kevux_e;
+ #else
+ main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_resolve_kevux_e;
+ main->setting.flag |= kt_tacocat_main_flag_resolve_classic_e;
+ #endif // _kt_resolve_default_kevux_
}
- uint8_t i = 0;
- f_number_unsigned_t index = 0;
-
- {
- const uint8_t parameters[] = {
- kt_tacocat_parameter_pid_name_e,
- kt_tacocat_parameter_pid_path_e,
- };
+ // Only process these when needed to avoid unnecessary operations.
+ if (main->callback.setting_load_send_receive && !(main->setting.flag & (kt_tacocat_main_flag_copyright_e | kt_tacocat_main_flag_version_e |kt_tacocat_main_flag_help_e))) {
+ main->callback.setting_load_send_receive(arguments, (void *) main);
+ }
- const f_string_static_t longs[] = {
- kt_tacocat_long_pid_name_s,
- kt_tacocat_long_pid_path_s,
- };
+ if (F_status_is_error_not(main->setting.state.status)) {
+ main->setting.state.status = F_none;
+ }
+ }
+#endif // _di_kt_tacocat_setting_load_
- f_string_dynamic_t * const strings[] = {
- &main->setting.pid_name,
- &main->setting.pid_path,
- };
+#ifndef _di_kt_tacocat_setting_load_send_receive_
+ void kt_tacocat_setting_load_send_receive(const f_console_arguments_t arguments, void * const void_main) {
- for (; i < 2; ++i) {
+ if (!void_main) return;
- if (main->program.parameters.array[parameters[i]].result & f_console_result_value_e) {
- index = main->program.parameters.array[parameters[i]].values.array[main->program.parameters.array[parameters[i]].values.used - 1];
+ kt_tacocat_main_t * const main = (kt_tacocat_main_t *) void_main;
- if (main->program.parameters.arguments.array[index].used) {
- strings[i]->used = 0;
+ const uint8_t parameters[] = {
+ kt_tacocat_parameter_receive_e,
+ kt_tacocat_parameter_send_e,
+ };
- main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], strings[i]);
+ const f_string_static_t longs[] = {
+ kt_tacocat_long_receive_s,
+ kt_tacocat_long_send_s,
+ };
- if (F_status_is_error(main->setting.state.status)) {
- macro_setting_load_print_first();
+ f_string_dynamics_t * const strings[] = {
+ &main->setting.receives,
+ &main->setting.sends,
+ };
- kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_string_dynamic_append_nulless));
+ f_files_t * const files[] = {
+ &main->setting.file_receives,
+ &main->setting.file_sends,
+ };
- return;
- }
- }
- else {
- main->setting.state.status = F_status_set_error(F_parameter);
+ const bool const is_receive[] = {
+ F_true,
+ F_false,
+ };
- macro_setting_load_print_first();
+ f_number_unsigned_t j = 0;
+ f_number_unsigned_t k = 0;
+ f_number_unsigned_t index = 0;
+ f_number_unsigned_t length = 0;
+ f_status_t failed = F_none;
+ struct hostent host;
+ f_network_family_ip_t family = f_network_family_ip_t_initialize;
- fll_program_print_error_parameter_empty_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]);
+ for (uint8_t i = 0; i < 2; ++i) {
- return;
- }
- }
- else if (main->program.parameters.array[parameters[i]].result & f_console_result_found_e) {
+ if (main->program.parameters.array[parameters[i]].result & f_console_result_value_e) {
+ if (main->program.parameters.array[parameters[i]].values.used % 2) {
main->setting.state.status = F_status_set_error(F_parameter);
- macro_setting_load_print_first();
-
- fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]);
-
- return;
- }
- } // for
- }
-
- // Only process these when needed to avoid unnecessary operations.
- if (!(main->setting.flag & (kt_tacocat_main_flag_copyright_e | kt_tacocat_main_flag_version_e |kt_tacocat_main_flag_help_e))) {
- const uint8_t parameters[] = {
- kt_tacocat_parameter_from_e,
- kt_tacocat_parameter_to_e,
- };
-
- const f_string_static_t longs[] = {
- kt_tacocat_long_from_s,
- kt_tacocat_long_to_s,
- };
-
- f_string_dynamics_t * const strings[] = {
- &main->setting.froms,
- &main->setting.tos,
- };
-
- const bool const must_exists[] = {
- F_true,
- F_false,
- };
-
- f_number_unsigned_t j = 0;
- f_number_unsigned_t k = 0;
- f_number_unsigned_t length = 0;
- f_status_t failed = F_none;
- struct hostent host;
- f_network_family_ip_t family = f_network_family_ip_t_initialize;
-
- for (i = 0; i < 2; ++i) {
-
- if (main->program.parameters.array[parameters[i]].result & f_console_result_value_e) {
- strings[i]->used = 0;
-
- main->setting.state.status = f_string_dynamics_increase_by(main->program.parameters.array[parameters[i]].values.used, strings[i]);
-
- 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(f_string_dynamics_increase_by));
-
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
-
- continue;
+ if ((main->setting.flag & kt_tacocat_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+ fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
}
- for (j = 0; j < main->program.parameters.array[parameters[i]].values.used; ++j) {
-
- index = main->program.parameters.array[parameters[i]].values.array[j];
- strings[i]->array[j].used = 0;
+ fll_program_print_error_parameter_missing_value_requires_amount(&main->program.error, f_console_symbol_long_normal_s, longs[i], kt_tacocat_two_s);
- 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) {
+ if (F_status_is_error_not(failed)) {
+ failed = main->setting.state.status;
+ }
- // 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]);
+ continue;
+ }
- if (F_status_is_error(main->setting.state.status)) {
- macro_setting_load_print_first();
+ strings[i]->used = 0;
- kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_string_dynamic_increase_by));
+ main->setting.state.status = f_string_dynamics_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, strings[i]);
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamics_increase_by);
- continue;
- }
+ main->setting.state.status = f_files_increase_by(main->program.parameters.array[parameters[i]].values.used / 2, files[i]);
- 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_files_increase_by);
- if (F_status_is_error(main->setting.state.status)) {
- macro_setting_load_print_first();
+ for (j = 0; j < main->program.parameters.array[parameters[i]].values.used; j += 2) {
- kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_string_dynamic_append_nulless));
+ // First parameter value represents the network address or the socket file path.
+ index = main->program.parameters.array[parameters[i]].values.array[j];
+ strings[i]->array[j].used = 0;
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ 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) {
- continue;
- }
+ // 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]);
- // 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;
- strings[i]->array[j].string[strings[i]->array[j].used + 1] = f_string_ascii_slash_forward_s.string[0];
+ macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_increase_by);
- if (must_exists[i]) {
- main->setting.state.status = f_file_exists(strings[i]->array[j], F_true);
+ main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &strings[i]->array[j]);
- if (F_status_is_error(main->setting.state.status)) {
- macro_setting_load_print_first();
+ macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_append_nulless);
- kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(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;
+ strings[i]->array[j].string[strings[i]->array[j].used + 1] = f_string_ascii_slash_forward_s.string[0];
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ if (is_receive[i]) {
+ main->setting.state.status = f_file_exists(strings[i]->array[j], F_true);
- continue;
- }
- }
+ macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_append_nulless);
}
- else {
- memset(&host, 0, sizeof(struct hostent));
+ }
+ 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);
+ main->setting.state.status = f_network_from_ip_name(main->program.parameters.arguments.array[index], &host);
- if (F_status_is_error(main->setting.state.status)) {
- macro_setting_load_print_first();
+ // @todo provide network-specific error messages.
+ macro_setting_load_handle_send_receive_error_continue_basic(f_network_from_ip_name);
- // @todo provide network-specific error messages.
- 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));
- continue;
+ if (F_status_is_error_not(failed)) {
+ failed = main->setting.state.status;
}
- if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) {
- macro_setting_load_print_first();
+ continue;
+ }
- // @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));
+ // Two is added to support a trailing NULL and a type character.
+ main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 2, &strings[i]->array[j]);
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_increase_by);
- continue;
- }
+ // Randomly select one of the addresses when there are more than one.
+ if (host.h_addr_list[1]) {
+ k = 2;
- // Two is added to support a trailing NULL and a type character.
- main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 2, &strings[i]->array[j]);
+ while (host.h_addr_list[k++]);
- if (F_status_is_error(main->setting.state.status)) {
- macro_setting_load_print_first();
+ // 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;
+ }
- kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_string_dynamic_increase_by));
+ // Two is added to support a trailing NULL and a type character.
+ main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 2, &strings[i]->array[j]);
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ macro_setting_load_handle_send_receive_error_continue_basic(f_string_dynamic_increase_by);
- continue;
- }
+ if (host.h_addrtype == AF_INET) {
+ 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]);
+ }
- // Randomly select one of the addresses when there are more than one.
- if (host.h_addr_list[1]) {
- k = 2;
+ main->setting.state.status = f_network_to_ip_string(family, &strings[i]->array[j]);
- while (host.h_addr_list[k++]);
+ if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) {
+ macro_setting_load_print_first();
- // 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;
+ // @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;
}
- // Two is added to support a trailing NULL and a type character.
- main->setting.state.status = f_string_dynamic_increase_by(INET6_ADDRSTRLEN + 2, &strings[i]->array[j]);
+ continue;
+ }
- if (F_status_is_error(main->setting.state.status)) {
- macro_setting_load_print_first();
+ // The terminating NULL, past the used length.
+ strings[i]->array[j].string[strings[i]->array[j].used] = 0;
+ strings[i]->array[j].string[strings[i]->array[j].used + 1] = (family.type & f_network_family_ip_4_e)
+ ? f_string_ascii_4_s.string[0]
+ : f_string_ascii_6_s.string[0];
+ }
+ else {
+ // @todo Kevux DNS resolution.
+ }
+ }
+ else {
+ main->setting.state.status = F_status_set_error(F_parameter);
- kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_string_dynamic_increase_by));
+ macro_setting_load_print_first();
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ fll_program_print_error_parameter_empty_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]);
- continue;
- }
+ if (F_status_is_error_not(failed)) {
+ failed = main->setting.state.status;
+ }
- if (host.h_addrtype == AF_INET) {
- 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]);
- }
+ continue;
+ }
- main->setting.state.status = f_network_to_ip_string(family, &strings[i]->array[j]);
+ // The second parameter value represents the local file to read from or write to.
+ index = main->program.parameters.array[parameters[i]].values.array[j + 1];
- if (main->setting.state.status == F_data_not || !host.h_addr_list || !host.h_addr_list[0]) {
- macro_setting_load_print_first();
+ if (main->program.parameters.arguments.array[index].used) {
- // @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));
+ // Make sure the current file is closed.
+ f_file_close(&files[i]->array[files[i]->used]);
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ 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;
+ }
+ 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;
+ }
- continue;
- }
+ 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]);
- // the terminating NULL, past the used length.
- strings[i]->array[j].string[strings[i]->array[j].used] = 0;
- strings[i]->array[j].string[strings[i]->array[j].used + 1] = (family.type & f_network_family_ip_4_e)
- ? f_string_ascii_4_s.string[0]
- : f_string_ascii_6_s.string[0];
- }
+ 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 {
- main->setting.state.status = F_status_set_error(F_parameter);
-
- macro_setting_load_print_first();
+ ++files[i]->used;
+ }
+ }
+ else {
+ main->setting.state.status = F_status_set_error(F_parameter);
- fll_program_print_error_parameter_empty_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]);
+ macro_setting_load_print_first();
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ fll_program_print_error_parameter_empty_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]);
- continue;
+ if (F_status_is_error_not(failed)) {
+ failed = main->setting.state.status;
}
- } // for
- }
- else if (main->program.parameters.array[parameters[i]].result & f_console_result_found_e) {
- main->setting.state.status = F_status_set_error(F_parameter);
- macro_setting_load_print_first();
+ continue;
+ }
+ } // for
+ }
+ else if (main->program.parameters.array[parameters[i]].result & f_console_result_found_e) {
+ main->setting.state.status = F_status_set_error(F_parameter);
- fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]);
+ macro_setting_load_print_first();
- if (F_status_is_error_not(failed)) {
- failed = main->setting.state.status;
- }
+ fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]);
- continue;
+ if (F_status_is_error_not(failed)) {
+ failed = main->setting.state.status;
}
- } // for
- if (F_status_is_error(failed)) {
- main->setting.state.status = failed;
+ continue;
}
+ } // for
+
+ if (F_status_is_error(failed)) {
+ main->setting.state.status = failed;
}
}
#endif // _di_kt_tacocat_setting_load_
* @param main
* The main program and settings data.
*
- * The setting.flag has kt_tacocat_flag_option_used_e forcibly cleared on the start of this function.
- *
* This alters setting.status:
* F_none on success.
- * F_data_not on success but nothing was provided to operate with.
*
* F_parameter (with error bit) on parameter error.
*
* Errors (with error bit) from: f_console_parameter_process().
- * Errors (with error bit) from: f_file_stream_open().
- * Errors (with error bit) from: f_string_dynamics_resize().
+ * Errors (with error bit) from: f_string_dynamic_append_nulless().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ * Errors (with error bit) from: fll_program_parameter_process_verbosity().
+ *
+ * Errors (with error bit) from: kt_tacocat_setting_load_send_receive().
*
* @see f_console_parameter_process()
- * @see f_file_stream_open()
- * @see f_string_dynamics_resize()
+ * @see f_string_dynamic_append_nulless()
+ * @see fll_program_parameter_process_context()
+ * @see fll_program_parameter_process_verbosity()
+ *
+ * @see kt_tacocat_setting_load_send_receive()
*/
#ifndef _di_kt_tacocat_setting_load_
extern void kt_tacocat_setting_load(const f_console_arguments_t arguments, kt_tacocat_main_t * const main);
#endif // _di_kt_tacocat_setting_load_
+/**
+ * Perform the standard program setting load process for the send and receive parameters.
+ *
+ * This will perform any DNS resolutions as necessary and open any appropriate files.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately returns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program and settings data.
+ *
+ * This must be of type kt_tacocat_main_t.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * F_parameter (with error bit) on parameter error.
+ *
+ * Errors (with error bit) from: f_file_exists().
+ * Errors (with error bit) from: f_file_open().
+ * Errors (with error bit) from: f_files_increase_by().
+ * Errors (with error bit) from: f_network_from_ip_name().
+ * Errors (with error bit) from: f_string_dynamic_append_nulless().
+ * Errors (with error bit) from: f_string_dynamic_increase_by().
+ * Errors (with error bit) from: f_string_dynamics_increase_by().
+ *
+ * Errors (with error bit) from: main.callback.setting_load_send_receive().
+ *
+ * @see f_file_exists()
+ * @see f_file_open()
+ * @see f_files_increase_by()
+ * @see f_network_from_ip_name()
+ * @see f_string_dynamic_append_nulless()
+ * @see f_string_dynamic_increase_by()
+ * @see f_string_dynamics_increase_by()
+ */
+#ifndef _di_kt_tacocat_setting_load_send_receive_
+ 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_
+
#ifdef __cplusplus
} // extern "C"
#endif
* kt_tacocat_signal_*_d:
* - check: When not using threads, this is how often to perform the check (lower numbers incur more kernel I/O).
* - check_failsafe: When using threads, how many consecutive failures to check signal before aborting (as a recursion failsafe).
+ *
+ * kt_tacocat_block_size_*_d:
+ * - receive: The block size in bytes to use when sending packets.
+ * - send: The block size in bytes to use when receiving packets.
*/
#ifndef _di_kt_tacocat_d_
#define kt_tacocat_allocation_console_d 4
#define kt_tacocat_signal_check_d 20000
#define kt_tacocat_signal_check_failsafe_d 20000
+
+ #define kt_tacocat_block_size_receive_d 65535
+ #define kt_tacocat_block_size_send_d 65535
#endif // _di_kt_tacocat_d_
/**
* The program macros.
*
- * 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_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:
+ * 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.
*/
#ifndef _di_kt_tacocat_macros_d_
#define macro_setting_load_print_first() \
if ((main->setting.flag & kt_tacocat_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) { \
fll_print_dynamic_raw(f_string_eol_s, main->program.message.to); \
}
+
+ #define macro_setting_load_handle_send_receive_error_continue_basic(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; \
+ } \
+ \
+ continue; \
+ }
+
+ #define macro_setting_load_handle_send_receive_error_file_continue_basic(method, name, operation, type) \
+ if (F_status_is_error(main->setting.state.status)) { \
+ macro_setting_load_print_first(); \
+ \
+ kt_tacocat_print_error_file(&main->program.error, macro_kt_tacocat_f(method), name, operation, type); \
+ \
+ if (F_status_is_error_not(failed)) { \
+ failed = main->setting.state.status; \
+ } \
+ \
+ continue; \
+ }
#endif // _di_kt_tacocat_macro_d_
#ifdef __cplusplus
* Flags passed to the main function or program.
*
* kt_tacocat_main_flag_*_e:
- * - none: No flags set.
- * - background: Specify daemonize the program, running it as a background process.
- * - copyright: Print copyright.
- * - from: The socket to receive from is specified.
- * - to: The socket to write to is specified.
- * - pid: Specify a pid file to use.
- * - print_first: When set, print new line to message output on program begin after loading settings.
- * - print_last: When set, print new line to message output on program end.
- * - resolve: The name resolution method.
- * - help: Print help.
- * - version: Print version.
+ * - none: No flags set.
+ * - copyright: Print copyright.
+ * - print_first: When set, print new line to message output on program begin after loading settings.
+ * - print_last: When set, print new line to message output on program end.
+ * - receive: The address or socket to receive from is specified.
+ * - resolve_classic: Follow the classic Domain Name Resolution method.
+ * - resolve_kevux: Follow the Kevux Domain Name Resolution method.
+ * - send: The address or socket send to is specified.
+ * - help: Print help.
+ * - version: Print version.
+ *
+ * For resolve_classic and resolve_kevux flags:
+ * The classic method utilizes the /etc/resolv.conf traditional method.
+ * Under classic, the http://, https://, etc.. act as normal.
+ *
+ * The Kevux method utilizes /etc/resolution/ method.
+ * Under Kevux, the web:// represents the traditional DNS, but kevux:// might represent Kevux network.
+ * For example web://www.google.com:443/ would be the same as https://www.google.com/, following DNS via /etc/resolution/dns/web.conf or /etc/resolution/host/web.conf.
+ * For example kevux://www.google.com:443/ would be a different server than google, following DNS via /etc/resolution/dns/kevux.conf or /etc/resolution/host/kevux.conf.
+ * The Kevux method also supports local DNS entries ie (~/.resolution/dns/kevux.conf or ~/.resolution/host/kevux.conf).
+ * @todo The Kevux method will be implemented in a library (project resolution and libresolution), re-introducing and expanding on the Turtle Kevux resolv.conf extensions that Kevin hacked into uClibc several years back.
*/
#ifndef _di_kt_tacocat_flag_e_
enum {
- kt_tacocat_main_flag_none_e = 0x0,
- kt_tacocat_main_flag_background_e = 0x1,
- kt_tacocat_main_flag_copyright_e = 0x2,
- kt_tacocat_main_flag_from_e = 0x4,
- kt_tacocat_main_flag_help_e = 0x8,
- kt_tacocat_main_flag_pid_e = 0x10,
- kt_tacocat_main_flag_print_first_e = 0x20,
- kt_tacocat_main_flag_print_last_e = 0x40,
- kt_tacocat_main_flag_resolve_e = 0x80,
- kt_tacocat_main_flag_to_e = 0x100,
- kt_tacocat_main_flag_version_e = 0x200,
+ kt_tacocat_main_flag_none_e = 0x0,
+ kt_tacocat_main_flag_copyright_e = 0x1,
+ kt_tacocat_main_flag_help_e = 0x2,
+ kt_tacocat_main_flag_print_first_e = 0x4,
+ kt_tacocat_main_flag_print_last_e = 0x8,
+ kt_tacocat_main_flag_receive_e = 0x10,
+ kt_tacocat_main_flag_resolve_classic_e = 0x20,
+ kt_tacocat_main_flag_resolve_kevux_e = 0x40,
+ kt_tacocat_main_flag_resolve_e = 0x80,
+ kt_tacocat_main_flag_send_e = 0x100,
+ kt_tacocat_main_flag_version_e = 0x200,
}; // enum
#endif // _di_kt_tacocat_flag_e_
kt_tacocat_parameter_line_first_no_e,
kt_tacocat_parameter_line_last_no_e,
- kt_tacocat_parameter_background_e,
- kt_tacocat_parameter_from_e,
- kt_tacocat_parameter_pid_e,
- kt_tacocat_parameter_pid_name_e,
- kt_tacocat_parameter_pid_path_e,
+ kt_tacocat_parameter_receive_e,
kt_tacocat_parameter_resolve_e,
- kt_tacocat_parameter_to_e,
+ kt_tacocat_parameter_send_e,
}; // enum
#define kt_tacocat_console_parameter_t_initialize \
{ \
macro_fll_program_console_parameter_standard_initialize, \
\
- macro_f_console_parameter_t_initialize_3(kt_tacocat_short_background_s, kt_tacocat_long_background_s, 0, f_console_flag_normal_e), \
- macro_f_console_parameter_t_initialize_3(kt_tacocat_short_from_s, kt_tacocat_long_from_s, 1, f_console_flag_normal_e), \
- macro_f_console_parameter_t_initialize_3(kt_tacocat_short_pid_s, kt_tacocat_long_pid_s, 0, f_console_flag_normal_e), \
- macro_f_console_parameter_t_initialize_3(kt_tacocat_short_pid_name_s, kt_tacocat_long_pid_name_s, 1, f_console_flag_normal_e), \
- macro_f_console_parameter_t_initialize_3(kt_tacocat_short_pid_path_s, kt_tacocat_long_pid_path_s, 1, f_console_flag_normal_e), \
+ macro_f_console_parameter_t_initialize_3(kt_tacocat_short_receive_s, kt_tacocat_long_receive_s, 2, f_console_flag_normal_e), \
macro_f_console_parameter_t_initialize_3(kt_tacocat_short_resolve_s, kt_tacocat_long_resolve_s, 1, f_console_flag_normal_e), \
- macro_f_console_parameter_t_initialize_3(kt_tacocat_short_to_s, kt_tacocat_long_to_s, 1, f_console_flag_normal_e), \
+ macro_f_console_parameter_t_initialize_3(kt_tacocat_short_send_s, kt_tacocat_long_send_s, 2, f_console_flag_normal_e), \
}
- #define kt_tacocat_parameter_total_d 20
+ #define kt_tacocat_parameter_total_d 16
#endif // _di_kt_tacocat_parameter_e_
/**
}; // enum
#endif // _di_kt_tacocat_print_flag_e_
-/**
- * Flags for specifying the Domain Name Resolution method.
- *
- * The classic method utilizes the /etc/resolv.conf traditional method.
- * Under classic, the http://, https://, etc.. act as normal.
- *
- * The Kevux method utilizes /etc/resolution/ method.
- * Under Kevux, the web:// represents the traditional DNS, but kevux:// might represent Kevux network.
- * For example web://www.google.com:443/ would be the same as https://www.google.com/, following DNS via /etc/resolution/dns/web.conf or /etc/resolution/host/web.conf.
- * For example kevux://www.google.com:443/ would be a different server than google, following DNS via /etc/resolution/dns/kevux.conf or /etc/resolution/host/kevux.conf.
- * The Kevux method also supports local DNS entries ie (~/.resolution/dns/kevux.conf or ~/.resolution/host/kevux.conf).
- * @todo The Kevux method will be implemented in a library (project resolution and libresolution), re-introducing and expanding on the Turtle Kevux resolv.conf extensions that Kevin hacked into uClibc several years back.
- *
- * kt_tacocat_resolve_method_*_e:
- * - none: No resolution method set.
- * - classic: Follow the classic Domain Name Resolution method.
- * - kevux: Follow the Kevux Domain Name Resolution method.
- */
-#ifndef _di_kt_tacocat_resolve_method_e_
- enum {
- kt_tacocat_resolve_method_none_e = 0x0,
- kt_tacocat_resolve_method_classic_e = 0x1,
- kt_tacocat_resolve_method_kevux_e = 0x2,
- }; // enum
-#endif // _di_kt_tacocat_flag_e_
-
#ifdef __cplusplus
} // extern "C"
#endif
#ifndef _di_kt_tacocat_f_a_
const f_string_t kt_tacocat_f_a[] = {
"f_console_parameter_process",
+ "f_file_open",
+ "f_files_increase_by",
"f_network_from_ip_name",
"f_string_append_nulless",
"f_string_dynamic_append_nulless",
#ifndef _di_kt_tacocat_f_e_
enum {
kt_tacocat_f_f_console_parameter_process_e,
+ 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_string_append_nulless_e,
kt_tacocat_f_f_string_dynamic_append_nulless_e,
#endif // _di_kt_tacocat_program_name_s_
#ifndef kt_tacocat_program_help_parameters_s_
- const f_string_static_t kt_tacocat_program_help_parameters_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_program_help_parameters_s, 0, KT_TACOCAT_program_help_parameters_s_length);
+ // Not used.
#endif // _di_utf8_program_help_parameters_s_
#ifndef _di_kt_tacocat_s_
+ const f_string_static_t kt_tacocat_classic_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_classic_s, 0, KT_TACOCAT_classic_s_length);
+ const f_string_static_t kt_tacocat_kevux_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_kevux_s, 0, KT_TACOCAT_kevux_s_length);
+ const f_string_static_t kt_tacocat_file_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_file_s, 0, KT_TACOCAT_file_s_length);
const f_string_static_t kt_tacocat_network_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_network_s, 0, KT_TACOCAT_network_s_length);
- const f_string_static_t kt_tacocat_pid_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_pid_s, 0, KT_TACOCAT_pid_s_length);
+ const f_string_static_t kt_tacocat_network_or_socket_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_network_or_socket_s, 0, KT_TACOCAT_network_or_socket_s_length);
const f_string_static_t kt_tacocat_socket_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_socket_s, 0, KT_TACOCAT_socket_s_length);
const f_string_static_t kt_tacocat_tacocat_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_tacocat_s, 0, KT_TACOCAT_tacocat_s_length);
+ const f_string_static_t kt_tacocat_two_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_two_s, 0, KT_TACOCAT_two_s_length);
#endif // _di_kt_tacocat_s_
-#ifndef _di_kt_tacocat_pid_s_
- const f_string_static_t kt_tacocat_pid_path_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_pid_path_s, 0, KT_TACOCAT_pid_path_s_length);
-#endif // _di_kt_tacocat_pid_s_
-
#ifndef _di_kt_tacocat_parameter_s_
- const f_string_static_t kt_tacocat_short_background_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_background_s, 0, KT_TACOCAT_short_background_s_length);
- const f_string_static_t kt_tacocat_short_from_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_from_s, 0, KT_TACOCAT_short_from_s_length);
- const f_string_static_t kt_tacocat_short_pid_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_pid_s, 0, KT_TACOCAT_short_pid_s_length);
- const f_string_static_t kt_tacocat_short_pid_name_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_pid_name_s, 0, KT_TACOCAT_short_pid_name_s_length);
- const f_string_static_t kt_tacocat_short_pid_path_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_pid_path_s, 0, KT_TACOCAT_short_pid_path_s_length);
+ const f_string_static_t kt_tacocat_short_receive_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_receive_s, 0, KT_TACOCAT_short_receive_s_length);
const f_string_static_t kt_tacocat_short_resolve_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_resolve_s, 0, KT_TACOCAT_short_resolve_s_length);
- const f_string_static_t kt_tacocat_short_to_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_to_s, 0, KT_TACOCAT_short_to_s_length);
+ const f_string_static_t kt_tacocat_short_send_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_send_s, 0, KT_TACOCAT_short_send_s_length);
- const f_string_static_t kt_tacocat_long_background_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_background_s, 0, KT_TACOCAT_long_background_s_length);
- const f_string_static_t kt_tacocat_long_from_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_from_s, 0, KT_TACOCAT_long_from_s_length);
- const f_string_static_t kt_tacocat_long_pid_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_pid_s, 0, KT_TACOCAT_long_pid_s_length);
- const f_string_static_t kt_tacocat_long_pid_name_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_pid_name_s, 0, KT_TACOCAT_long_pid_name_s_length);
- const f_string_static_t kt_tacocat_long_pid_path_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_pid_path_s, 0, KT_TACOCAT_long_pid_path_s_length);
+ const f_string_static_t kt_tacocat_long_receive_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_receive_s, 0, KT_TACOCAT_long_receive_s_length);
const f_string_static_t kt_tacocat_long_resolve_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_resolve_s, 0, KT_TACOCAT_long_resolve_s_length);
- const f_string_static_t kt_tacocat_long_to_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_to_s, 0, KT_TACOCAT_long_to_s_length);
+ const f_string_static_t kt_tacocat_long_send_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_send_s, 0, KT_TACOCAT_long_send_s_length);
#endif // _di_kt_tacocat_parameter_s_
#ifdef __cplusplus
* The program help related data.
*/
#ifndef kt_tacocat_program_help_parameters_s_
- #define KT_TACOCAT_program_help_parameters_s "socket(s)/address(s)"
- #define KT_TACOCAT_program_help_parameters_s_length 20
-
- extern const f_string_static_t kt_tacocat_program_help_parameters_s;
+ // Not used.
#endif // _di_utf8_program_help_parameters_s_
/**
* kt_tacocat_*_s: Arbitrary strings.
*/
#ifndef _di_kt_tacocat_s_
- #define KT_TACOCAT_network_s "network"
- #define KT_TACOCAT_pid_s "pid"
- #define KT_TACOCAT_socket_s "socket"
- #define KT_TACOCAT_tacocat_s "tacocat"
-
- #define KT_TACOCAT_network_s_length 7
- #define KT_TACOCAT_pid_s_length 3
- #define KT_TACOCAT_socket_s_length 6
- #define KT_TACOCAT_tacocat_s_length 7
-
+ #define KT_TACOCAT_classic_s "classic"
+ #define KT_TACOCAT_kevux_s "kevux"
+ #define KT_TACOCAT_file_s "file"
+ #define KT_TACOCAT_network_s "network"
+ #define KT_TACOCAT_network_or_socket_s "network / socket"
+ #define KT_TACOCAT_socket_s "socket"
+ #define KT_TACOCAT_tacocat_s "tacocat"
+ #define KT_TACOCAT_two_s "two"
+
+ #define KT_TACOCAT_classic_s_length 7
+ #define KT_TACOCAT_kevux_s_length 5
+ #define KT_TACOCAT_file_s_length 4
+ #define KT_TACOCAT_network_s_length 7
+ #define KT_TACOCAT_network_or_socket_s_length 16
+ #define KT_TACOCAT_socket_s_length 6
+ #define KT_TACOCAT_tacocat_s_length 7
+ #define KT_TACOCAT_two_s_length 3
+
+ extern const f_string_static_t kt_tacocat_classic_s;
+ extern const f_string_static_t kt_tacocat_kevux_s;
+ extern const f_string_static_t kt_tacocat_file_s;
extern const f_string_static_t kt_tacocat_network_s;
- extern const f_string_static_t kt_tacocat_pid_s;
+ extern const f_string_static_t kt_tacocat_network_or_socket_s;
extern const f_string_static_t kt_tacocat_socket_s;
extern const f_string_static_t kt_tacocat_tacocat_s;
+ extern const f_string_static_t kt_tacocat_two_s;
#endif // _di_kt_tacocat_s_
/**
- * Additional strings directly associated with PID file and path.
- *
- * kt_tacocat_pid_*_s: Pid Path specific strings.
- */
-#ifndef _di_kt_tacocat_pid_s_
- #ifndef KT_TACOCAT_pid_path_s
- #define KT_TACOCAT_pid_path_s "/var/run/tacocat/"
- #endif // KT_TACOCAT_pid_path_s
-
- #ifndef KT_TACOCAT_pid_path_s_length
- #define KT_TACOCAT_pid_path_s_length 17
- #endif // KT_TACOCAT_pid_path_s_length
-
- extern const f_string_static_t kt_tacocat_pid_path_s;
-#endif // _di_kt_tacocat_pid_s_
-
-/**
* The main program parameters.
*/
#ifndef _di_kt_tacocat_parameter_s_
- #define KT_TACOCAT_short_background_s "b"
- #define KT_TACOCAT_short_from_s "f"
- #define KT_TACOCAT_short_pid_s "p"
- #define KT_TACOCAT_short_pid_name_s "N"
- #define KT_TACOCAT_short_pid_path_s "P"
+ #define KT_TACOCAT_short_receive_s "r"
#define KT_TACOCAT_short_resolve_s "R"
- #define KT_TACOCAT_short_to_s "t"
+ #define KT_TACOCAT_short_send_s "s"
- #define KT_TACOCAT_long_background_s "background"
- #define KT_TACOCAT_long_from_s "from"
- #define KT_TACOCAT_long_pid_s "pid"
- #define KT_TACOCAT_long_pid_name_s "pid_name"
- #define KT_TACOCAT_long_pid_path_s "pid_path"
+ #define KT_TACOCAT_long_receive_s "receive"
#define KT_TACOCAT_long_resolve_s "resolve"
- #define KT_TACOCAT_long_to_s "to"
+ #define KT_TACOCAT_long_send_s "send"
- #define KT_TACOCAT_short_background_s_length 1
- #define KT_TACOCAT_short_from_s_length 1
- #define KT_TACOCAT_short_pid_s_length 1
- #define KT_TACOCAT_short_pid_name_s_length 1
- #define KT_TACOCAT_short_pid_path_s_length 1
+ #define KT_TACOCAT_short_receive_s_length 1
#define KT_TACOCAT_short_resolve_s_length 1
- #define KT_TACOCAT_short_to_s_length 1
+ #define KT_TACOCAT_short_send_s_length 1
- #define KT_TACOCAT_long_background_s_length 10
- #define KT_TACOCAT_long_from_s_length 4
- #define KT_TACOCAT_long_pid_s_length 3
- #define KT_TACOCAT_long_pid_name_s_length 8
- #define KT_TACOCAT_long_pid_path_s_length 8
+ #define KT_TACOCAT_long_receive_s_length 7
#define KT_TACOCAT_long_resolve_s_length 7
- #define KT_TACOCAT_long_to_s_length 2
+ #define KT_TACOCAT_long_send_s_length 4
- extern const f_string_static_t kt_tacocat_short_background_s;
- extern const f_string_static_t kt_tacocat_short_from_s;
- extern const f_string_static_t kt_tacocat_short_pid_s;
- extern const f_string_static_t kt_tacocat_short_pid_name_s;
- extern const f_string_static_t kt_tacocat_short_pid_path_s;
+ extern const f_string_static_t kt_tacocat_short_receive_s;
extern const f_string_static_t kt_tacocat_short_resolve_s;
- extern const f_string_static_t kt_tacocat_short_to_s;
+ extern const f_string_static_t kt_tacocat_short_send_s;
- extern const f_string_static_t kt_tacocat_long_background_s;
- extern const f_string_static_t kt_tacocat_long_from_s;
- extern const f_string_static_t kt_tacocat_long_pid_s;
- extern const f_string_static_t kt_tacocat_long_pid_name_s;
- extern const f_string_static_t kt_tacocat_long_pid_path_s;
+ extern const f_string_static_t kt_tacocat_long_receive_s;
extern const f_string_static_t kt_tacocat_long_resolve_s;
- extern const f_string_static_t kt_tacocat_long_to_s;
+ extern const f_string_static_t kt_tacocat_long_send_s;
#endif // _di_kt_tacocat_parameter_s_
#ifdef __cplusplus
f_number_unsigned_t i = 0;
- for (; i < setting->file_froms.used ; ++i) {
- f_file_close(&setting->file_froms.array[i]);
+ for (; i < setting->file_receives.used ; ++i) {
+ f_file_close(&setting->file_receives.array[i]);
} // for
- for (; i < setting->file_tos.used ; ++i) {
- f_file_close(&setting->file_tos.array[i]);
+ for (; i < setting->file_sends.used ; ++i) {
+ f_file_close(&setting->file_sends.array[i]);
} // for
+ f_files_resize(0, &setting->file_receives);
+ f_files_resize(0, &setting->file_sends);
+
f_string_dynamic_resize(0, &setting->buffer);
f_string_dynamic_resize(0, &setting->pid_path);
f_string_dynamic_resize(0, &setting->pid_name);
- f_string_dynamics_resize(0, &setting->froms);
- f_string_dynamics_resize(0, &setting->tos);
+ f_string_dynamics_resize(0, &setting->receives);
+ f_string_dynamics_resize(0, &setting->sends);
return F_none;
}
*
* flag: Flags passed to the main function.
*
+ * block_size_receive: The size in bytes to used to represent a block when receiving packets.
+ * block_size_send: The size in bytes to used to represent a block when sending packets.
+ *
* status_thread: A status used eclusively by the threaded signal handler.
* state: The state data used when processing data.
*
- * pid_file: The PID file.
- * file_froms: An array of input files.
- * file_tos: An array of output files.
+ * pid_file: The PID file.
+ * file_receives: An array of input files.
+ * file_sends: An array of output files.
*
* buffer: A string buffer used for caching purposes.
* pid_name: The name of the PID file without the path and without the file extension (.pid).
* pid_path: A file path to the directory containing the PID file.
*
- * froms: An array of buffers for receiving data from clients.
- * tos: An array of buffers for sending data to clients.
+ * receives: An array of buffers for receiving data receive clients.
+ * sends: An array of buffers for sending data send clients.
*/
#ifndef _di_kt_tacocat_setting_t_
typedef struct {
uint64_t flag;
+ f_number_unsigned_t block_size_receive;
+ f_number_unsigned_t block_size_send;
+
f_status_t status_thread;
f_state_t state;
f_file_t pid_file;
- f_files_t file_froms;
- f_files_t file_tos;
+ f_files_t file_receives;
+ f_files_t file_sends;
f_string_dynamic_t buffer;
f_string_dynamic_t pid_path;
f_string_dynamic_t pid_name;
- f_string_dynamics_t froms;
- f_string_dynamics_t tos;
+ f_string_dynamics_t receives;
+ f_string_dynamics_t sends;
} kt_tacocat_setting_t;
#define kt_tacocat_setting_t_initialize \
{ \
kt_tacocat_main_flag_none_e, \
+ kt_tacocat_block_size_receive_d, \
+ kt_tacocat_block_size_send_d, \
F_none, \
macro_f_state_t_initialize_1(kt_tacocat_allocation_large_d, kt_tacocat_allocation_small_d, F_none, 0, 0, &fll_program_standard_signal_handle, 0, 0, 0, 0), \
f_file_t_initialize, \
#endif // _di_kt_tacocat_setting_t_
/**
+ * The TacocaT callbacks.
+ *
+ * setting_load_send_receive: Process loading the settings regarding send and receive, handling DNS resolution and file opening as needed.
+ */
+#ifndef _di_kt_tacocat_callback_t_
+ typedef struct {
+ void (*setting_load_send_receive)(const f_console_arguments_t arguments, void * const main);
+ } kt_tacocat_callback_t;
+
+ #define kt_tacocat_callback_t_initialize \
+ { \
+ 0, \
+ }
+#endif // _di_kt_tacocat_callback_t_
+
+/**
* The main program data as a single structure.
*
- * program: The main program data.
- * setting: The settings data.
+ * program: The main program data.
+ * setting: The settings data.
+ * callback: The program callbacks.
*/
#ifndef _di_kt_tacocat_main_t_
typedef struct {
fll_program_data_t program;
kt_tacocat_setting_t setting;
+ kt_tacocat_callback_t callback;
} kt_tacocat_main_t;
#define kt_tacocat_main_t_initialize \
{ \
fll_program_data_t_initialize, \
kt_tacocat_setting_t_initialize, \
+ kt_tacocat_callback_t_initialize, \
}
#endif // _di_kt_tacocat_main_t_
data.program.parameters.used = kt_tacocat_parameter_total_d;
data.program.environment = envp;
+ data.callback.setting_load_send_receive = kt_tacocat_setting_load_send_receive;
+
if (f_pipe_input_exists()) {
data.program.pipe = fll_program_data_pipe_input_e;
}
}
#endif // _di_kt_tacocat_print_error_file_
+#ifndef _di_kt_tacocat_print_error_parameter_value_resolve_unknown_
+ f_status_t kt_tacocat_print_error_parameter_value_resolve_unknown(fl_print_t * const print, const f_string_dynamic_t unknown) {
+
+ if (!print || !print->custom) return F_status_set_error(F_output_not);
+ if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+ f_file_stream_lock(print->to);
+
+ fl_print_format("%[%QThe parameter%] ", print->to, print->set->error, print->prefix, print->set->error);
+ fl_print_format("%[%Q%Q%]", print->to, print->set->notable, f_console_symbol_long_normal_s, kt_tacocat_long_resolve_s, print->set->notable);
+ fl_print_format(" %[may only be either '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[%Q%]", print->to, print->set->notable, kt_tacocat_classic_s, print->set->notable);
+ fl_print_format("%' or '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[%Q%]", 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("%[%Q%]", 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);
+
+ f_file_stream_unlock(print->to);
+
+ return F_none;
+ }
+#endif // _di_kt_tacocat_print_error_parameter_value_resolve_unknown_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t kt_tacocat_print_error_file(fl_print_t * const print, const f_string_t function, const f_string_static_t name, const f_string_static_t operation, const uint8_t type);
#endif // _di_kt_tacocat_print_error_file_
+/**
+ * Print error message for when an unknown value for the resolve parameter is provided.
+ *
+ * @param print
+ * The output structure to print to.
+ *
+ * This does not alter print.custom.setting.state.status.
+ * @param unknown
+ * The string representing the unknown value passed to the resolve parameter.
+ *
+ * @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 fll_error_file_print()
+ */
+#ifndef _di_kt_tacocat_print_error_parameter_value_resolve_unknown_
+ extern f_status_t kt_tacocat_print_error_parameter_value_resolve_unknown(fl_print_t * const print, const f_string_dynamic_t unknown);
+#endif // _di_kt_tacocat_print_error_parameter_value_resolve_unknown_
+
#ifdef __cplusplus
} // extern "C"
#endif
f_print_dynamic_raw(f_string_eol_s, print->to);
- fll_program_print_help_option(print, kt_tacocat_short_background_s, kt_tacocat_long_background_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Run this program in the background.");
- fll_program_print_help_option(print, kt_tacocat_short_from_s, kt_tacocat_long_from_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Specify an address or socket file to listen to.");
- fll_program_print_help_option(print, kt_tacocat_short_pid_s, kt_tacocat_long_pid_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Enable the use of a PID file.");
- fll_program_print_help_option(print, kt_tacocat_short_pid_name_s, kt_tacocat_long_pid_name_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Specify a custom PID file name, without the '.pid' extension.");
- fll_program_print_help_option(print, kt_tacocat_short_pid_path_s, kt_tacocat_long_pid_path_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Specify a custom directory path where the PID file is located.");
- fll_program_print_help_option(print, kt_tacocat_short_resolve_s, kt_tacocat_long_resolve_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Specify a custom DNS resolution methodology.");
- fll_program_print_help_option(print, kt_tacocat_short_to_s, kt_tacocat_long_to_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Specify an address or socket file to transmit to.");
+ fll_program_print_help_option(print, kt_tacocat_short_receive_s, kt_tacocat_long_receive_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Specify an address or socket file to listen to and a file to write to.");
+ fll_program_print_help_option(print, kt_tacocat_short_resolve_s, kt_tacocat_long_resolve_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Specify a custom DNS resolution methodology.");
+ fll_program_print_help_option(print, kt_tacocat_short_send_s, kt_tacocat_long_send_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Specify an address or socket file send transmit to and a file to read from.");
f_print_dynamic_raw(f_string_eol_s, print->to);
- fll_program_print_help_usage(print, kt_tacocat_program_name_s, kt_tacocat_program_help_parameters_s);
+ fll_program_print_help_usage(print, kt_tacocat_program_name_s, f_string_empty_s);
- fl_print_format("%r The parameters '%[%r%r%]', ", print->to, f_string_eol_s, context.set.notable, f_console_symbol_long_normal_s, kt_tacocat_long_from_s, context.set.notable);
- fl_print_format("'%[%r%r%]' ", print->to, context.set.notable, f_console_symbol_long_normal_s, kt_tacocat_long_to_s, context.set.notable);
+ fl_print_format("%r The parameters '%[%r%r%]', ", print->to, f_string_eol_s, context.set.notable, f_console_symbol_long_normal_s, kt_tacocat_long_receive_s, context.set.notable);
+ fl_print_format("'%[%r%r%]' ", print->to, context.set.notable, f_console_symbol_long_normal_s, kt_tacocat_long_send_s, context.set.notable);
fl_print_format("may either represent a network address or a local socket file.%r%r", print->to, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" The %[%r%r%] and the ", print->to, print->set->notable, f_console_symbol_long_normal_s, kt_tacocat_long_receive_s, print->set->notable);
+ fl_print_format("%[%r%r%] options require 2 additional parameters:", print->to, print->set->notable, f_console_symbol_long_normal_s, kt_tacocat_long_send_s, print->set->notable);
+ fl_print_format(" %[<%]%r%[>%]", print->to, print->set->notable, print->set->notable, kt_tacocat_network_or_socket_s, print->set->notable, print->set->notable);
+ fl_print_format(" %[<%]%r%[>%].%r", print->to, print->set->notable, print->set->notable, kt_tacocat_file_s, print->set->notable, print->set->notable, f_string_eol_s);
+
+ fl_print_format(" %[%r%]: The network address or the socket file to use.%r", print->to, print->set->notable, kt_tacocat_network_or_socket_s, print->set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%]: The local file to use to read from or to write to.%r%r", print->to, print->set->notable, kt_tacocat_file_s, print->set->notable, f_string_eol_s, f_string_eol_s);
+
fl_print_format(" A local socket file must begin with an absolute path like '%[/var/www.example.com%]' and ", print->to, context.set.notable, context.set.notable);
fl_print_format("'%[/var/example.socket%]', or it must begin with a relative absolute path, like ", print->to, context.set.notable, context.set.notable);
fl_print_format("'%[./www.example.com%]' and %[./example.socket%].%r%r", print->to, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s, f_string_eol_s);
fl_print_format(" Any address that does not begin with either a single slash '%[/%]' (%[U+002F%])' or ", print->to, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
fl_print_format("a dot and a single slash '%[./%]' and (%[U+002E%]) ", print->to, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
- fl_print_format("(%[U+002F%]) is considered a network address.%r%r", print->to, context.set.notable, context.set.notable, f_string_eol_s, f_string_eol_s);
+ fl_print_format("(%[U+002F%]) is considered a network address.%r", print->to, context.set.notable, context.set.notable, f_string_eol_s);
f_file_stream_flush(print->to);
f_file_stream_unlock(print->to);
--- /dev/null
+#include "tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_process_main_
+ void kt_tacocat_process_main(kt_tacocat_main_t * const main) {
+
+ if (!main) return;
+
+ // @todo:
+ // 1: Establish connections.
+ // 2: read / write from files.
+ // 3: work or wait until told to terminate.
+ // 4: terminate.
+
+ main->setting.state.status = F_none;
+ }
+#endif // _di_kt_tacocat_process_main_
+
+#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_process_h
+#define _kt_tacocat_process_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform the main TacocaT processing.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This alters main.setting.state.status:
+ * F_none on success.
+ */
+#ifndef _di_kt_tacocat_process_main_
+ extern void kt_tacocat_process_main(kt_tacocat_main_t * const main);
+#endif // _di_kt_tacocat_process_main_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_process_h
return;
}
- // @todo do stuff (do everything).
+ kt_tacocat_process_main(main);
if (main->program.signal_received) {
main->setting.state.status = F_status_set_error(F_interrupt);
#include <fll/level_0/type.h>
#include <fll/level_0/status.h>
#include <fll/level_0/memory.h>
+#include <fll/level_0/type_array.h>
+#include <fll/level_0/type_array_file.h>
#include <fll/level_0/string.h>
#include <fll/level_0/color.h>
+#include <fll/level_0/compare.h>
#include <fll/level_0/console.h>
#include <fll/level_0/file.h>
#include <fll/level_0/network.h>
#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/process.h>
#include <program/kevux/tools/tacocat/main/signal.h>
#include <program/kevux/tools/tacocat/main/thread.h>