From cd724104a8cfaad4670fcc33a11c0908f168d17c Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 27 Jun 2023 22:13:12 -0500 Subject: [PATCH] Feature: Initial addition of the "TacocaT" program. The "TacocaT" program is intended to be similar to netcat. To concatenate multiple network connections in this context simply means to transfer data from one point to another. The intent and purpose of this program is really to test my network connection software. This program is only stubbed out at this point in time. I need to figure out how I want the data files to be setup. The network code is not implemented at all, yet. I also decided to tease my plans on improving the existing Kevux DNS alternative network resolution methodology. --- data/build/tacocat/defines | 3 + data/build/tacocat/dependencies | 22 +++ data/build/tacocat/fakefile | 27 +++ data/build/tacocat/settings | 88 +++++++++ sources/c/tacocat/main/common.c | 275 ++++++++++++++++++++++++++++ sources/c/tacocat/main/common.h | 55 ++++++ sources/c/tacocat/main/common/define.c | 9 + sources/c/tacocat/main/common/define.h | 44 +++++ sources/c/tacocat/main/common/enumeration.c | 9 + sources/c/tacocat/main/common/enumeration.h | 151 +++++++++++++++ sources/c/tacocat/main/common/print.c | 20 ++ sources/c/tacocat/main/common/print.h | 55 ++++++ sources/c/tacocat/main/common/string.c | 51 ++++++ sources/c/tacocat/main/common/string.h | 168 +++++++++++++++++ sources/c/tacocat/main/common/type.c | 46 +++++ sources/c/tacocat/main/common/type.h | 128 +++++++++++++ sources/c/tacocat/main/main.c | 82 +++++++++ sources/c/tacocat/main/main.h | 38 ++++ sources/c/tacocat/main/print/error.c | 33 ++++ sources/c/tacocat/main/print/error.h | 72 ++++++++ sources/c/tacocat/main/print/message.c | 55 ++++++ sources/c/tacocat/main/print/message.h | 54 ++++++ sources/c/tacocat/main/print/verbose.c | 9 + sources/c/tacocat/main/print/verbose.h | 23 +++ sources/c/tacocat/main/print/warning.c | 9 + sources/c/tacocat/main/print/warning.h | 23 +++ sources/c/tacocat/main/signal.c | 100 ++++++++++ sources/c/tacocat/main/signal.h | 82 +++++++++ sources/c/tacocat/main/tacocat.c | 62 +++++++ sources/c/tacocat/main/tacocat.h | 99 ++++++++++ sources/c/tacocat/main/thread.c | 22 +++ sources/c/tacocat/main/thread.h | 46 +++++ 32 files changed, 1960 insertions(+) create mode 100644 data/build/tacocat/defines create mode 100644 data/build/tacocat/dependencies create mode 100644 data/build/tacocat/fakefile create mode 100644 data/build/tacocat/settings create mode 100644 sources/c/tacocat/main/common.c create mode 100644 sources/c/tacocat/main/common.h create mode 100644 sources/c/tacocat/main/common/define.c create mode 100644 sources/c/tacocat/main/common/define.h create mode 100644 sources/c/tacocat/main/common/enumeration.c create mode 100644 sources/c/tacocat/main/common/enumeration.h create mode 100644 sources/c/tacocat/main/common/print.c create mode 100644 sources/c/tacocat/main/common/print.h create mode 100644 sources/c/tacocat/main/common/string.c create mode 100644 sources/c/tacocat/main/common/string.h create mode 100644 sources/c/tacocat/main/common/type.c create mode 100644 sources/c/tacocat/main/common/type.h create mode 100644 sources/c/tacocat/main/main.c create mode 100644 sources/c/tacocat/main/main.h create mode 100644 sources/c/tacocat/main/print/error.c create mode 100644 sources/c/tacocat/main/print/error.h create mode 100644 sources/c/tacocat/main/print/message.c create mode 100644 sources/c/tacocat/main/print/message.h create mode 100644 sources/c/tacocat/main/print/verbose.c create mode 100644 sources/c/tacocat/main/print/verbose.h create mode 100644 sources/c/tacocat/main/print/warning.c create mode 100644 sources/c/tacocat/main/print/warning.h create mode 100644 sources/c/tacocat/main/signal.c create mode 100644 sources/c/tacocat/main/signal.h create mode 100644 sources/c/tacocat/main/tacocat.c create mode 100644 sources/c/tacocat/main/tacocat.h create mode 100644 sources/c/tacocat/main/thread.c create mode 100644 sources/c/tacocat/main/thread.h diff --git a/data/build/tacocat/defines b/data/build/tacocat/defines new file mode 100644 index 0000000..db4cb2d --- /dev/null +++ b/data/build/tacocat/defines @@ -0,0 +1,3 @@ +# fss-0000 + +_di_thread_support_ Disable thread support, handling signals without using a separate thread. diff --git a/data/build/tacocat/dependencies b/data/build/tacocat/dependencies new file mode 100644 index 0000000..fdb3a14 --- /dev/null +++ b/data/build/tacocat/dependencies @@ -0,0 +1,22 @@ +# fss-0000 + +f_type +f_status +f_memory +f_type_array +f_string +f_utf +f_color +f_console +f_conversion +f_pipe +f_print +f_signal +f_thread + +fl_conversion +fl_print + +fll_error +fll_print +fll_program diff --git a/data/build/tacocat/fakefile b/data/build/tacocat/fakefile new file mode 100644 index 0000000..3d56d44 --- /dev/null +++ b/data/build/tacocat/fakefile @@ -0,0 +1,27 @@ +# fss-0005 iki-0002 + +settings: + fail exit + modes individual level monolithic clang test fanalyzer coverage threaded threadless + + environment PATH LD_LIBRARY_PATH + environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + +main: + build tacocat/settings + +install: + shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' + +help: + print + print context:'title'Fakefile Options for Kevux Tools Network Concatenate Software.context:'reset' + + print + print The following operations are available\: + print " - context:'notable'help:context:'reset' Perform the help operation, printing this message." + print " - context:'notable'install:context:'reset' A helper operation that simply calls the ./install.sh script with default settings." + print " - context:'notable'main:context:'reset' The default compilation using the build settings mode." + + print + print The context:'notable'install context:'reset'operation supports the context:'notable'work,context:'reset' context:'notable'verbosity,context:'reset' and context:'notable'color context:'reset'parameters. diff --git a/data/build/tacocat/settings b/data/build/tacocat/settings new file mode 100644 index 0000000..ac00118 --- /dev/null +++ b/data/build/tacocat/settings @@ -0,0 +1,88 @@ +# fss-0001 +# +# Builds the main tacocat program of the project. +# +# Modes: +# - individual: Compile using per project (individual) libraries, does not handle thread or threadless cases. +# - individual_thread: This is required when compiling in individual mode with "thread" mode. +# - level: Compile using per level libraries. +# - monolithic: Compile using per monolithic libraries. +# - clang: Use clang rather than the default, which is generally gcc. +# - test: Compile for a test, such as unit testing. +# - fanalyzer: Compile using GCC's -fanalyzer compile time option. +# - thread: Compile with thread support. +# - threadless: Compile without thread support. +# + +build_name tacocat + +version_major 0 +version_minor 5 +version_micro 0 +version_file micro +version_target minor + +modes individual individual_thread level monolithic clang test fanalyzer thread threadless +modes_default monolithic thread + +build_compiler gcc +build_compiler-clang clang +build_indexer ar +build_indexer_arguments rcs +build_language c + +build_libraries -lc +build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_conversion -lfl_print -lf_color -lf_console -lf_conversion -lf_memory -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_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_program main/main.c + +build_sources_documentation man + +build_script yes +build_shared yes +build_static no + +path_headers program/kevux/tools/tacocat +path_library_script script +path_library_shared shared +path_library_static static +path_object_script script +path_object_shared shared +path_object_static static +path_program_script script +path_program_shared shared +path_program_static static +path_sources sources/c/tacocat + +has_path_standard no +preserve_path_headers yes + +search_exclusive yes +search_shared yes +search_static yes + +environment PATH LD_LIBRARY_PATH +environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + +#defines -D_di_libcap_ +defines -D_libcap_legacy_only_ +defines-threadless -D_di_thread_support_ +defines-thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_ + +flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses -Wno-missing-braces +flags-thread -pthread +flags-clang -Wno-logical-op-parentheses +flags-test -O0 -fstack-protector -Wall +flags-fanalyzer -fanalyzer +flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/ + +flags_library -fPIC +flags_object -fPIC +flags_program -fPIE diff --git a/sources/c/tacocat/main/common.c b/sources/c/tacocat/main/common.c new file mode 100644 index 0000000..45515f2 --- /dev/null +++ b/sources/c/tacocat/main/common.c @@ -0,0 +1,275 @@ +#include "tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_setting_load_ + void kt_tacocat_setting_load(const f_console_arguments_t arguments, kt_tacocat_main_t * const main) { + + if (!main) return; + + main->setting.state.step_small = kt_tacocat_allocation_console_d; + + f_console_parameter_process(arguments, &main->program.parameters, &main->setting.state, 0); + + main->setting.state.step_small = kt_tacocat_allocation_small_d; + + + // Identify and pocess first/last parameters. + if (main->program.parameters.array[kt_tacocat_parameter_line_first_no_e].result & f_console_result_found_e) { + main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_print_first_e; + } + else { + main->setting.flag |= kt_tacocat_main_flag_print_first_e; + } + + if (main->program.parameters.array[kt_tacocat_parameter_line_last_no_e].result & f_console_result_found_e) { + main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_print_last_e; + } + else { + main->setting.flag |= kt_tacocat_main_flag_print_last_e; + } + + if (F_status_is_error(main->setting.state.status)) { + 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); + } + + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_console_parameter_process)); + + return; + } + + { + f_uint16s_t choices = f_uint16s_t_initialize; + + // Identify and prioritize "color context" parameters. + { + uint16_t choices_array[3] = { kt_tacocat_parameter_no_color_e, kt_tacocat_parameter_light_e, kt_tacocat_parameter_dark_e }; + choices.array = choices_array; + choices.used = 3; + + const uint8_t modes[3] = { f_color_mode_not_e, f_color_mode_light_e, f_color_mode_dark_e }; + + main->setting.state.status = fll_program_parameter_process_context(choices, modes, F_true, &main->program); + + if (F_status_is_error(main->setting.state.status)) { + 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); + } + + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(fll_program_parameter_process_context)); + + return; + } + } + + // Identify and prioritize "verbosity" parameters. + { + uint16_t choices_array[5] = { kt_tacocat_parameter_verbosity_quiet_e, kt_tacocat_parameter_verbosity_error_e, kt_tacocat_parameter_verbosity_verbose_e, kt_tacocat_parameter_verbosity_debug_e, kt_tacocat_parameter_verbosity_normal_e }; + choices.array = choices_array; + choices.used = 5; + + const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e }; + + main->setting.state.status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, &main->program); + + if (F_status_is_error(main->setting.state.status)) { + 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); + } + + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(fll_program_parameter_process_verbosity)); + + return; + } + } + } + + 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; + } + else { + main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_help_e; + } + + if (main->program.parameters.array[kt_tacocat_parameter_version_e].result & f_console_result_found_e) { + main->setting.flag |= kt_tacocat_main_flag_version_e; + } + else { + main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_version_e; + } + + if (main->program.parameters.array[kt_tacocat_parameter_copyright_e].result & f_console_result_found_e) { + main->setting.flag |= kt_tacocat_main_flag_copyright_e; + } + else { + 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_pid_e].result & f_console_result_found_e) { + main->setting.flag |= kt_tacocat_main_flag_pid_e; + } + else { + main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_pid_e; + } + + 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, + }; + + const f_string_static_t longs[] = { + kt_tacocat_long_pid_name_s, + kt_tacocat_long_pid_path_s, + }; + + f_string_dynamic_t * const strings[] = { + &main->setting.pid_name, + &main->setting.pid_path, + }; + + for (; i < 2; ++i) { + + 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]; + + if (main->program.parameters.arguments.array[index].used) { + strings[i]->used = 0; + + main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], strings[i]); + + if (F_status_is_error(main->setting.state.status)) { + 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); + } + + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_string_dynamic_append_nulless)); + + return; + } + } + else { + main->setting.state.status = F_status_set_error(F_parameter); + + 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); + } + + fll_program_print_error_parameter_empty_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]); + + return; + } + } + else if (main->program.parameters.array[parameters[i]].result & f_console_result_found_e) { + main->setting.state.status = F_status_set_error(F_parameter); + + 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); + } + + fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]); + + return; + } + } // for + } + + { + 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, + }; + + f_number_unsigned_t j = 0; + + 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)) { + 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); + } + + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_string_dynamics_increase_by)); + + return; + } + + for (j = 0; j < main->program.parameters.array[parameters[i]].values.used; ++j) { + + index = main->program.parameters.array[parameters[i]].values.array[j]; + + if (main->program.parameters.arguments.array[index].used) { + strings[i]->array[j].used = 0; + + 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)) { + 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); + } + + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_string_dynamic_append_nulless)); + + return; + } + } + else { + main->setting.state.status = F_status_set_error(F_parameter); + + 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); + } + + fll_program_print_error_parameter_empty_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]); + + return; + } + } // 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); + + 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); + } + + fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, longs[i]); + + return; + } + } // for + } + } +#endif // _di_kt_tacocat_setting_load_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/common.h b/sources/c/tacocat/main/common.h new file mode 100644 index 0000000..8bf0264 --- /dev/null +++ b/sources/c/tacocat/main/common.h @@ -0,0 +1,55 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the common data structures. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_common_h +#define _kt_tacocat_common_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform the standard program setting load process. + * + * 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. + * + * 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(). + * + * @see f_console_parameter_process() + * @see f_file_stream_open() + * @see f_string_dynamics_resize() + */ +#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_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_common_h diff --git a/sources/c/tacocat/main/common/define.c b/sources/c/tacocat/main/common/define.c new file mode 100644 index 0000000..87f1956 --- /dev/null +++ b/sources/c/tacocat/main/common/define.c @@ -0,0 +1,9 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/common/define.h b/sources/c/tacocat/main/common/define.h new file mode 100644 index 0000000..ad41b9e --- /dev/null +++ b/sources/c/tacocat/main/common/define.h @@ -0,0 +1,44 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the common define types. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_common_define_h +#define _kt_tacocat_common_define_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The program defines. + * + * kt_tacocat_allocation_*_d: + * - console: An allocation step used for small buffers specifically for console parameter. + * - large: An allocation step used for buffers that are anticipated to have large buffers. + * - small: An allocation step used for buffers that are anticipated to have small buffers. + * + * 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). + */ +#ifndef _di_kt_tacocat_d_ + #define kt_tacocat_allocation_console_d 4 + #define kt_tacocat_allocation_large_d 2048 + #define kt_tacocat_allocation_small_d 128 + + #define kt_tacocat_signal_check_d 20000 + #define kt_tacocat_signal_check_failsafe_d 20000 +#endif // _di_kt_tacocat_d_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_common_define_h diff --git a/sources/c/tacocat/main/common/enumeration.c b/sources/c/tacocat/main/common/enumeration.c new file mode 100644 index 0000000..87f1956 --- /dev/null +++ b/sources/c/tacocat/main/common/enumeration.c @@ -0,0 +1,9 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/common/enumeration.h b/sources/c/tacocat/main/common/enumeration.h new file mode 100644 index 0000000..37a7898 --- /dev/null +++ b/sources/c/tacocat/main/common/enumeration.h @@ -0,0 +1,151 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the common enumeration types. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_common_enumeration_h +#define _kt_tacocat_common_enumeration_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * 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. + */ +#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, + }; // enum +#endif // _di_kt_tacocat_flag_e_ + +/** + * The main program parameters. + */ +#ifndef _di_kt_tacocat_parameter_e_ + enum { + kt_tacocat_parameter_help_e, + kt_tacocat_parameter_copyright_e, + kt_tacocat_parameter_light_e, + kt_tacocat_parameter_dark_e, + kt_tacocat_parameter_no_color_e, + kt_tacocat_parameter_verbosity_quiet_e, + kt_tacocat_parameter_verbosity_error_e, + kt_tacocat_parameter_verbosity_normal_e, + kt_tacocat_parameter_verbosity_verbose_e, + kt_tacocat_parameter_verbosity_debug_e, + kt_tacocat_parameter_version_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_resolve_e, + kt_tacocat_parameter_to_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_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), \ + } + + #define kt_tacocat_parameter_total_d 20 +#endif // _di_kt_tacocat_parameter_e_ + +/** + * Flags for fine-tuned print control. + * + * kt_tacocat_print_flag_*_e: + * - none: No flags set. + * - debug: Stream is for debug printing. + * - error: Stream is for error printing. + * - file: Stream is associated with a file. + * - in: Stream is a source file. + * - message: Stream is for message printing. + * - out: Stream is a destination file. + * - warning: Stream is for warning printing. + */ +#ifndef _di_kt_tacocat_print_flag_e_ + enum { + kt_tacocat_print_flag_none_e = 0x0, + kt_tacocat_print_flag_debug_e = 0x1, + kt_tacocat_print_flag_error_e = 0x2, + kt_tacocat_print_flag_file_e = 0x4, + kt_tacocat_print_flag_in_e = 0x8, + kt_tacocat_print_flag_message_e = 0x10, + kt_tacocat_print_flag_out_e = 0x20, + kt_tacocat_print_flag_warning_e = 0x40, + }; // 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 + +#endif // _kt_tacocat_common_enumeration_h diff --git a/sources/c/tacocat/main/common/print.c b/sources/c/tacocat/main/common/print.c new file mode 100644 index 0000000..40fdc1e --- /dev/null +++ b/sources/c/tacocat/main/common/print.c @@ -0,0 +1,20 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_f_a_ + const f_string_t kt_tacocat_f_a[] = { + "f_console_parameter_process", + "f_string_dynamic_append_nulless", + "f_string_dynamics_increase_by", + "f_thread_create", + "fll_program_parameter_process_context", + "fll_program_parameter_process_verbosity", + }; +#endif // _di_kt_tacocat_f_a_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/common/print.h b/sources/c/tacocat/main/common/print.h new file mode 100644 index 0000000..40507b7 --- /dev/null +++ b/sources/c/tacocat/main/common/print.h @@ -0,0 +1,55 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the common print functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_common_print_h +#define _kt_tacocat_common_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A special array of strings intended for representing funciton names. + * + * These are primarily used for printing errors with the function names. + * + * The macro macro_kt_tacocat_f() is used to reference the array index by the enum name. + * + * macro_kt_tacocat_f(): + * - name: The name of the function. + */ +#ifndef _di_kt_tacocat_f_a_ + extern const f_string_t kt_tacocat_f_a[]; + + #define macro_kt_tacocat_f(name) kt_tacocat_f_a[kt_tacocat_f_##name##_e] +#endif // _di_kt_tacocat_f_a_ + +/** + * An enum representing specific indexes within the above array. + * + * This is a convenience enum used to make code slightly more readable. + */ +#ifndef _di_kt_tacocat_f_e_ + enum { + kt_tacocat_f_f_console_parameter_process_e, + kt_tacocat_f_f_string_dynamic_append_nulless_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, + }; // enum +#endif // _di_kt_tacocat_f_e_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_common_print_h diff --git a/sources/c/tacocat/main/common/string.c b/sources/c/tacocat/main/common/string.c new file mode 100644 index 0000000..0cbf725 --- /dev/null +++ b/sources/c/tacocat/main/common/string.c @@ -0,0 +1,51 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_program_version_s_ + const f_string_static_t kt_tacocat_program_version_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_program_version_s, 0, KT_TACOCAT_program_version_s_length); +#endif // _di_kt_tacocat_program_version_s_ + +#ifndef _di_kt_tacocat_program_name_s_ + const f_string_static_t kt_tacocat_program_name_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_program_name_s, 0, KT_TACOCAT_program_name_s_length); + const f_string_static_t kt_tacocat_program_name_long_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_program_name_long_s, 0, KT_TACOCAT_program_name_long_s_length); +#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); +#endif // _di_utf8_program_help_parameters_s_ + +#ifndef _di_kt_tacocat_s_ + 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_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); +#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_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_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_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); +#endif // _di_kt_tacocat_parameter_s_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/common/string.h b/sources/c/tacocat/main/common/string.h new file mode 100644 index 0000000..00337da --- /dev/null +++ b/sources/c/tacocat/main/common/string.h @@ -0,0 +1,168 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the common string structures. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_common_string_h +#define _kt_tacocat_common_string_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The program version. + */ +#ifndef _di_kt_tacocat_program_version_s_ + #define KT_TACOCAT_program_version_major_s F_string_ascii_0_s + #define KT_TACOCAT_program_version_minor_s F_string_ascii_5_s + #define KT_TACOCAT_program_version_micro_s F_string_ascii_0_s + + #define KT_TACOCAT_program_version_major_s_length F_string_ascii_0_s_length + #define KT_TACOCAT_program_version_minor_s_length F_string_ascii_5_s_length + #define KT_TACOCAT_program_version_micro_s_length F_string_ascii_0_s_length + + #if !(defined(KT_TACOCAT_program_version_nano_prefix_s) && defined(KT_TACOCAT_program_version_nano_prefix_s_length)) + #define KT_TACOCAT_program_version_nano_prefix_s + #define KT_TACOCAT_program_version_nano_prefix_s_length 0 + #endif // !(defined(KT_TACOCAT_program_version_nano_prefix_s) && defined(KT_TACOCAT_program_version_nano_prefix_s_length)) + + #if !(defined(KT_TACOCAT_program_version_nano_s) && defined(KT_TACOCAT_program_version_nano_s_length)) + #define KT_TACOCAT_program_version_nano_s + #define KT_TACOCAT_program_version_nano_s_length 0 + #endif // !(defined(KT_TACOCAT_program_version_nano_s) && defined(KT_TACOCAT_program_version_nano_s_length)) + + #define KT_TACOCAT_program_version_s KT_TACOCAT_program_version_major_s F_string_ascii_period_s KT_TACOCAT_program_version_minor_s F_string_ascii_period_s KT_TACOCAT_program_version_micro_s KT_TACOCAT_program_version_nano_prefix_s KT_TACOCAT_program_version_nano_s + + #define KT_TACOCAT_program_version_s_length KT_TACOCAT_program_version_major_s_length + F_string_ascii_period_s_length + KT_TACOCAT_program_version_minor_s_length + F_string_ascii_period_s_length + KT_TACOCAT_program_version_micro_s_length + KT_TACOCAT_program_version_nano_prefix_s_length + KT_TACOCAT_program_version_nano_s_length + + extern const f_string_static_t kt_tacocat_program_version_s; +#endif // _di_kt_tacocat_program_version_s_ + +/** + * The program name. + */ +#ifndef _di_kt_tacocat_program_name_s_ + #define KT_TACOCAT_program_name_s "tacocat" + #define KT_TACOCAT_program_name_long_s "tacocat" + + #define KT_TACOCAT_program_name_s_length 7 + #define KT_TACOCAT_program_name_long_s_length 7 + + extern const f_string_static_t kt_tacocat_program_name_s; + extern const f_string_static_t kt_tacocat_program_name_long_s; +#endif // _di_kt_tacocat_program_name_s_ + +/** + * 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; +#endif // _di_utf8_program_help_parameters_s_ + +/** + * Additional strings used for various purposes. + * + * 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 + + 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_socket_s; + extern const f_string_static_t kt_tacocat_tacocat_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_resolve_s "R" + #define KT_TACOCAT_short_to_s "t" + + #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_resolve_s "resolve" + #define KT_TACOCAT_long_to_s "to" + + #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_resolve_s_length 1 + #define KT_TACOCAT_short_to_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_resolve_s_length 7 + #define KT_TACOCAT_long_to_s_length 2 + + 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_resolve_s; + extern const f_string_static_t kt_tacocat_short_to_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_resolve_s; + extern const f_string_static_t kt_tacocat_long_to_s; +#endif // _di_kt_tacocat_parameter_s_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_common_string_h diff --git a/sources/c/tacocat/main/common/type.c b/sources/c/tacocat/main/common/type.c new file mode 100644 index 0000000..356f37a --- /dev/null +++ b/sources/c/tacocat/main/common/type.c @@ -0,0 +1,46 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_main_delete_ + void kt_tacocat_main_delete(kt_tacocat_main_t * const main) { + + if (!main) return; + + fll_program_data_delete(&main->program); + kt_tacocat_setting_delete(&main->setting); + } +#endif // _di_kt_tacocat_main_delete_ + +#ifndef _di_kt_tacocat_setting_delete_ + f_status_t kt_tacocat_setting_delete(kt_tacocat_setting_t * const setting) { + + if (!setting) return F_status_set_error(F_parameter); + + f_file_close(&setting->pid_file); + + f_number_unsigned_t i = 0; + + for (; i < setting->file_froms.used ; ++i) { + f_file_close(&setting->file_froms.array[i]); + } // for + + for (; i < setting->file_tos.used ; ++i) { + f_file_close(&setting->file_tos.array[i]); + } // for + + 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); + + return F_none; + } +#endif // _di_kt_tacocat_setting_delete_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/common/type.h b/sources/c/tacocat/main/common/type.h new file mode 100644 index 0000000..2bd31bb --- /dev/null +++ b/sources/c/tacocat/main/common/type.h @@ -0,0 +1,128 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the common type structures. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_common_type_h +#define _kt_tacocat_common_type_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The main program settings. + * + * This is passed to the program-specific main entry point to designate program settings. + * These program settings are often processed from the program arguments (often called the command line arguments). + * + * flag: Flags passed to the main function. + * + * 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. + * + * 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. + */ +#ifndef _di_kt_tacocat_setting_t_ + typedef struct { + uint64_t flag; + + 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_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; + } kt_tacocat_setting_t; + + #define kt_tacocat_setting_t_initialize \ + { \ + kt_tacocat_main_flag_none_e, \ + 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, \ + f_files_t_initialize, \ + f_files_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamics_t_initialize, \ + f_string_dynamics_t_initialize, \ + } +#endif // _di_kt_tacocat_setting_t_ + +/** + * The main program data as a single structure. + * + * program: The main program data. + * setting: The settings data. + */ +#ifndef _di_kt_tacocat_main_t_ + typedef struct { + fll_program_data_t program; + kt_tacocat_setting_t setting; + } kt_tacocat_main_t; + + #define kt_tacocat_main_t_initialize \ + { \ + fll_program_data_t_initialize, \ + kt_tacocat_setting_t_initialize, \ + } +#endif // _di_kt_tacocat_main_t_ + +/** + * Deallocate main program data. + * + * @param setting_make + * The make setting data. + * + * This does not alter main.setting.state.status. + */ +#ifndef _di_kt_tacocat_main_delete_ + extern void kt_tacocat_main_delete(kt_tacocat_main_t * const main); +#endif // _di_kt_tacocat_main_delete_ + +/** + * Delete the program main setting data. + * + * @param setting + * The program main setting data. + * + * This does not alter setting.state.status. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_kt_tacocat_setting_delete_ + extern f_status_t kt_tacocat_setting_delete(kt_tacocat_setting_t * const setting); +#endif // _di_kt_tacocat_setting_delete_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_common_type_h diff --git a/sources/c/tacocat/main/main.c b/sources/c/tacocat/main/main.c new file mode 100644 index 0000000..5933cce --- /dev/null +++ b/sources/c/tacocat/main/main.c @@ -0,0 +1,82 @@ +#include "tacocat.h" +#include "main.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int main(const int argc, const f_string_t *argv, const f_string_t *envp) { + + kt_tacocat_main_t data = kt_tacocat_main_t_initialize; + + data.program.debug.flag |= kt_tacocat_print_flag_debug_e | kt_tacocat_print_flag_out_e; + data.program.error.flag |= kt_tacocat_print_flag_error_e | kt_tacocat_print_flag_out_e; + data.program.message.flag |= kt_tacocat_print_flag_message_e | kt_tacocat_print_flag_out_e; + data.program.output.flag |= kt_tacocat_print_flag_out_e; + data.program.warning.flag |= kt_tacocat_print_flag_warning_e | kt_tacocat_print_flag_out_e; + data.program.message.custom = (void *) &data; + data.program.output.custom = (void *) &data; + data.program.error.custom = (void *) &data; + data.program.warning.custom = (void *) &data; + data.program.debug.custom = (void *) &data; + + data.setting.state.data = (void *) &data; + + f_console_parameter_t parameters[] = kt_tacocat_console_parameter_t_initialize; + + data.program.parameters.array = parameters; + data.program.parameters.used = kt_tacocat_parameter_total_d; + data.program.environment = envp; + + if (f_pipe_input_exists()) { + data.program.pipe = fll_program_data_pipe_input_e; + } + + fll_program_standard_set_up(&data.program); + + #ifdef _di_thread_support_ + { + const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp); + + kt_tacocat_setting_load(arguments, &data); + } + + status_code_main(&data); + #else + { + f_thread_id_t id_signal; + + memset(&id_signal, 0, sizeof(f_thread_id_t)); + + data.setting.state.status = f_thread_create(0, &id_signal, &kt_tacocat_thread_signal, (void *) &data); + + if (F_status_is_error(data.setting.state.status)) { + kt_tacocat_print_error(&data.program.error, macro_kt_tacocat_f(f_thread_create)); + } + else { + { + const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp); + + kt_tacocat_setting_load(arguments, &data); + } + + if (!kt_tacocat_signal_check(&data)) { + kt_tacocat_main(&data); + } + + f_thread_cancel(id_signal); + f_thread_join(id_signal, 0); + } + } + #endif // _di_thread_support_ + + kt_tacocat_main_delete(&data); + + fll_program_standard_set_down(&data.program); + + return (F_status_is_error(data.setting.state.status) || data.setting.state.status == F_false) ? 1 : 0; +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/main.h b/sources/c/tacocat/main/main.h new file mode 100644 index 0000000..58011b0 --- /dev/null +++ b/sources/c/tacocat/main/main.h @@ -0,0 +1,38 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * This file is only ever included by main.c and should not normally be included anywhere else. + * Anything that wants to include this should be providing the "remove" program functionality in some manner. + */ +#ifndef _kt_remove_main_h +#define _kt_remove_main_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Standard program entry point. + * + * @param argc + * The number of arguments. + * @param argv + * The array of arguments. + * @param envp + * The array of all environment variables on program start. + * + * @return + * 0 on success. + * 1 on error. + */ +extern int main(const int argc, const f_string_t *argv, const f_string_t *envp); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_remove_main_h diff --git a/sources/c/tacocat/main/print/error.c b/sources/c/tacocat/main/print/error.c new file mode 100644 index 0000000..b024cfa --- /dev/null +++ b/sources/c/tacocat/main/print/error.c @@ -0,0 +1,33 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_print_error_ + f_status_t kt_tacocat_print_error(fl_print_t * const print, const f_string_t function) { + + if (!print || !print->custom) return F_status_set_error(F_output_not); + if (print->verbosity < f_console_verbosity_error_e) return F_output_not; + + fll_error_print(print, F_status_set_fine(((kt_tacocat_main_t *) print->custom)->setting.state.status), function, F_true); + + return F_none; + } +#endif // _di_kt_tacocat_print_error_ + +#ifndef _di_kt_tacocat_print_error_file_ + 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) { + + if (!print || !print->custom) return F_status_set_error(F_output_not); + if (print->verbosity < f_console_verbosity_error_e) return F_output_not; + + fll_error_file_print(print, F_status_set_fine(((kt_tacocat_main_t *) print->custom)->setting.state.status), function, F_true, name, operation, type); + + return F_none; + } +#endif // _di_kt_tacocat_print_error_file_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/print/error.h b/sources/c/tacocat/main/print/error.h new file mode 100644 index 0000000..a668383 --- /dev/null +++ b/sources/c/tacocat/main/print/error.h @@ -0,0 +1,72 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the print error functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_print_error_h +#define _kt_tacocat_print_error_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print generic error message regarding a function failing in some way. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + * + * @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_print() + */ +#ifndef _di_kt_tacocat_print_error_ + extern f_status_t kt_tacocat_print_error(fl_print_t * const print, const f_string_t function); +#endif // _di_kt_tacocat_print_error_ + +/** + * Print file related error or warning messages. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + * @param function + * The name of the function where the error happened. + * Set to 0 to disable. + * @param name + * The name of the file or directory. + * @param operation + * The operation that fails, such as 'create' or 'access'. + * @param type + * A valid file type code from the fll_error_file_type enum. + * + * @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_file_ + 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_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_print_error_h diff --git a/sources/c/tacocat/main/print/message.c b/sources/c/tacocat/main/print/message.c new file mode 100644 index 0000000..cbe5e0f --- /dev/null +++ b/sources/c/tacocat/main/print/message.c @@ -0,0 +1,55 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_print_message_help_ + f_status_t kt_tacocat_print_message_help(fl_print_t * const print, const f_color_context_t context) { + + if (!print || !print->custom) return F_status_set_error(F_output_not); + + kt_tacocat_main_t * const main = (kt_tacocat_main_t *) print->custom; + + f_file_stream_lock(print->to); + + fll_program_print_help_header(print, kt_tacocat_program_name_long_s, kt_tacocat_program_version_s); + + fll_program_print_help_option_standard(print); + + 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."); + + 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); + + 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("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(" 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); + + f_file_stream_flush(print->to); + f_file_stream_unlock(print->to); + + return F_none; + } +#endif // _di_kt_tacocat_print_message_help_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/print/message.h b/sources/c/tacocat/main/print/message.h new file mode 100644 index 0000000..d8e2ebf --- /dev/null +++ b/sources/c/tacocat/main/print/message.h @@ -0,0 +1,54 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the print message functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_print_message_h +#define _kt_tacocat_print_message_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print help. + * + * @param print + * The output structure to print to. + * + * This locks, uses, and unlocks the file stream. + * + * This does not alter print.custom.setting.state.status. + * @param context + * The color context settings. + * + * @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_flush() + * @see f_file_stream_lock() + * @see f_file_stream_unlock() + * @see f_print_dynamic_raw() + * @see fl_print_format() + * @see fll_program_print_help_header() + * @see fll_program_print_help_option() + * @see fll_program_print_help_option_long() + */ +#ifndef _di_kt_tacocat_print_message_help_ + extern f_status_t kt_tacocat_print_message_help(fl_print_t * const print, const f_color_context_t context); +#endif // _di_kt_tacocat_print_message_help_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_print_message_h diff --git a/sources/c/tacocat/main/print/verbose.c b/sources/c/tacocat/main/print/verbose.c new file mode 100644 index 0000000..87f1956 --- /dev/null +++ b/sources/c/tacocat/main/print/verbose.c @@ -0,0 +1,9 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/print/verbose.h b/sources/c/tacocat/main/print/verbose.h new file mode 100644 index 0000000..54b3215 --- /dev/null +++ b/sources/c/tacocat/main/print/verbose.h @@ -0,0 +1,23 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the print verbose functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_print_verbose_h +#define _kt_tacocat_print_verbose_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_print_verbose_h diff --git a/sources/c/tacocat/main/print/warning.c b/sources/c/tacocat/main/print/warning.c new file mode 100644 index 0000000..87f1956 --- /dev/null +++ b/sources/c/tacocat/main/print/warning.c @@ -0,0 +1,9 @@ +#include "../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/print/warning.h b/sources/c/tacocat/main/print/warning.h new file mode 100644 index 0000000..7cd756b --- /dev/null +++ b/sources/c/tacocat/main/print/warning.h @@ -0,0 +1,23 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Provides the print warning functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_print_warning_h +#define _kt_tacocat_print_warning_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_print_warning_h diff --git a/sources/c/tacocat/main/signal.c b/sources/c/tacocat/main/signal.c new file mode 100644 index 0000000..46a47d6 --- /dev/null +++ b/sources/c/tacocat/main/signal.c @@ -0,0 +1,100 @@ +#include "tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_kt_tacocat_signal_check_) && defined(_di_thread_support_) + f_status_t kt_tacocat_signal_check(kt_tacocat_main_t * const main) { + + if (!main) return F_false; + if (main->program.signal.id == -1) return F_false; + + if (!((++main->program.signal_check) % kt_tacocat_signal_check_d)) { + if (fll_program_standard_signal_received(&main->program)) return F_true; + + main->program.signal_check = 0; + } + + return F_false; + } +#endif // !defined(_di_kt_tacocat_signal_check_) && defined(_di_thread_support_) + +#if !defined(_di_kt_tacocat_signal_check_) && !defined(_di_thread_support_) + f_status_t kt_tacocat_signal_check(kt_tacocat_main_t * const main) { + + if (!main) return F_false; + if (main->program.signal.id == -1) return F_false; + if (main->program.signal_received) return F_true; + + return F_false; + } +#endif // !defined(_di_kt_tacocat_signal_check_) && !defined(_di_thread_support_) + +#if !defined(_di_kt_tacocat_signal_handler_) && !defined(_di_thread_support_) + void kt_tacocat_signal_handler(kt_tacocat_main_t * const main) { + + if (!main) return; + + siginfo_t information; + f_number_unsigned_t failsafe = 0; + + memset(&information, 0, sizeof(siginfo_t)); + + main->program.signal_received = 0; + + f_signal_set_empty(&main->program.signal.set); + f_signal_set_add(F_signal_abort, &main->program.signal.set); + f_signal_set_add(F_signal_broken_pipe, &main->program.signal.set); + f_signal_set_add(F_signal_hangup, &main->program.signal.set); + f_signal_set_add(F_signal_interrupt, &main->program.signal.set); + f_signal_set_add(F_signal_quit, &main->program.signal.set); + f_signal_set_add(F_signal_termination, &main->program.signal.set); + + if (main->program.signal.id == -1) { + main->setting.status_thread = f_signal_open(&main->program.signal); + + if (F_status_is_error(main->setting.status_thread)) { + main->program.signal_received = F_signal_abort; + + return; + } + } + + do { + memset(&information, 0, sizeof(siginfo_t)); + + main->setting.status_thread = f_signal_wait(&main->program.signal.set, &information); + + if (F_status_is_error(main->setting.status_thread) && F_status_set_fine(main->setting.status_thread) != F_interrupt) { + if (++failsafe >= kt_tacocat_signal_check_failsafe_d) break; + } + + switch (information.si_signo) { + case F_signal_abort: + case F_signal_broken_pipe: + case F_signal_hangup: + case F_signal_interrupt: + case F_signal_quit: + case F_signal_termination: + main->program.signal_received = information.si_signo; + + break; + } + + failsafe = 0; + main->setting.status_thread = F_none; + + } while (!main->program.signal_received); + + f_signal_close(&main->program.signal); + + if (F_status_is_error(main->setting.status_thread)) { + main->program.signal_received = F_signal_abort; + } + } +#endif // !defined(_di_kt_tacocat_signal_handler_) && !defined(_di_thread_support_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/signal.h b/sources/c/tacocat/main/signal.h new file mode 100644 index 0000000..bc5f375 --- /dev/null +++ b/sources/c/tacocat/main/signal.h @@ -0,0 +1,82 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _kt_tacocat_signal_h +#define _kt_tacocat_signal_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check to see if a signal is received. + * + * If main.signal is non-zero, then this handles the following signals: + * - F_signal_abort + * - F_signal_broken_pipe + * - F_signal_hangup + * - F_signal_interrupt + * - F_signal_quit + * - F_signal_termination + * + * There is a threaded and a non-threaded version of this. + * The non-threaded version checks periodically using kt_tacocat_signal_check_d and updates main->signal_check as needed. + * The threaded version checks the flag state which is set by a separate thread that is blocking until signal is received. + * + * @param main + * The main program and settings data. + * + * This does not alter main.setting.state.status. + * + * @return + * F_true on signal received. + * F_false otherwise. + * + * @see kt_tacocat_signal_handler() + * + * @see fll_program_standard_signal_received() + */ +#ifndef _di_kt_tacocat_signal_check_ + extern f_status_t kt_tacocat_signal_check(kt_tacocat_main_t * const main); +#endif // _di_kt_tacocat_signal_check_ + +/** + * Signal handler for signals/interrupts. + * + * This blocks until an expected signal is recieved. + * When an expected signal is received it then sets the + * + * If main.signal is non-zero, then this handles the following signals: + * - F_signal_abort + * - F_signal_broken_pipe + * - F_signal_hangup + * - F_signal_interrupt + * - F_signal_quit + * - F_signal_termination + * + * @param main + * The main program and settings data. + * + * This alters main.program.signal_received, setting it to a received signal. + * + * This alters setting.status: + * Errors (with error bit) from: f_signal_open() + * Errors (with error bit) from: f_signal_wait() + * + * @see f_signal_close() + * @see f_signal_open() + * @see f_signal_wait() + */ +#if !defined(_di_kt_tacocat_signal_handler_) && !defined(_di_thread_support_) + extern void kt_tacocat_signal_handler(kt_tacocat_main_t * const main); +#endif // !defined(_di_kt_tacocat_signal_handler_) && !defined(_di_thread_support_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_signal_h diff --git a/sources/c/tacocat/main/tacocat.c b/sources/c/tacocat/main/tacocat.c new file mode 100644 index 0000000..2308b02 --- /dev/null +++ b/sources/c/tacocat/main/tacocat.c @@ -0,0 +1,62 @@ +#include "tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_main_ + void kt_tacocat_main(kt_tacocat_main_t * const main) { + + if (!main) return; + + if (F_status_is_error(main->setting.state.status)) { + if ((main->setting.flag & kt_tacocat_main_flag_print_last_e) && main->program.message.verbosity > f_console_verbosity_error_e) { + fll_print_dynamic_raw(f_string_eol_s, main->program.message.to); + } + + return; + } + + 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); + } + + main->setting.state.status = F_none; + + if (main->setting.flag & (kt_tacocat_main_flag_help_e | kt_tacocat_main_flag_version_e | kt_tacocat_main_flag_copyright_e)) { + if (main->setting.flag & kt_tacocat_main_flag_help_e) { + kt_tacocat_print_message_help(&main->program.output, main->program.context); + } + else if (main->setting.flag & kt_tacocat_main_flag_version_e) { + fll_program_print_version(&main->program.message, kt_tacocat_program_version_s); + } + else if (main->setting.flag & kt_tacocat_main_flag_copyright_e) { + fll_program_print_copyright(&main->program.message); + } + + if ((main->setting.flag & kt_tacocat_main_flag_print_last_e) && main->program.message.verbosity > f_console_verbosity_error_e) { + fll_print_dynamic_raw(f_string_eol_s, main->program.message.to); + } + + return; + } + + // @todo do stuff (do everything). + + if (main->program.signal_received) { + main->setting.state.status = F_status_set_error(F_interrupt); + } + + if (main->setting.state.status == F_status_set_error(F_interrupt)) { + fll_program_print_signal_received(&main->program.warning, main->program.signal_received); + } + + if ((main->setting.flag & kt_tacocat_main_flag_print_last_e) && main->program.message.verbosity > f_console_verbosity_error_e) { + fll_print_dynamic_raw(f_string_eol_s, main->program.message.to); + } + } +#endif // _di_kt_tacocat_main_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/tacocat.h b/sources/c/tacocat/main/tacocat.h new file mode 100644 index 0000000..2f04f94 --- /dev/null +++ b/sources/c/tacocat/main/tacocat.h @@ -0,0 +1,99 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * This program provides a program to perform file, directory, and symbolic link remove file removals. + */ +#ifndef _kt_tacocat_h +#define _kt_tacocat_h + +// Libc includes. +#include +#include +#include +#include +#include + +// FLL-0 includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// FLL-1 includes. +#include +#include +#include + +// FLL-2 includes. +#include +#include +#include + +// Kevux Tools includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Execute main program. + * + * If main.signal is non-zero, then this blocks and handles the following signals: + * - F_signal_abort + * - F_signal_broken_pipe + * - F_signal_hangup + * - F_signal_interrupt + * - F_signal_quit + * - F_signal_termination + * + * @param main + * The main program and settings data. + * + * This alters main.setting.state.status: + * F_none on success. + * F_true on success when performing verification and verify passed. + * F_false on success when performing verification and verify failed. + * + * F_interrupt (with error bit) on (exit) signal received. + * + * Errors (with error bit) from: main.callback.process_normal(). + */ +#ifndef _di_kt_tacocat_main_ + extern void kt_tacocat_main(kt_tacocat_main_t * const main); +#endif // _di_kt_tacocat_main_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_h diff --git a/sources/c/tacocat/main/thread.c b/sources/c/tacocat/main/thread.c new file mode 100644 index 0000000..a2d6cd1 --- /dev/null +++ b/sources/c/tacocat/main/thread.c @@ -0,0 +1,22 @@ +#include "tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_kt_tacocat_thread_signal_) && !defined(_di_thread_support_) + void * kt_tacocat_thread_signal(void * const main) { + + f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); + + if (main) { + kt_tacocat_signal_handler((kt_tacocat_main_t *) main); + } + + return 0; + } +#endif // !defined(_di_kt_tacocat_thread_signal_) && !defined(_di_thread_support_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/thread.h b/sources/c/tacocat/main/thread.h new file mode 100644 index 0000000..8aa11d7 --- /dev/null +++ b/sources/c/tacocat/main/thread.h @@ -0,0 +1,46 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _kt_tacocat_thread_h +#define _kt_tacocat_thread_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Thread handler for signals/interrupts. + * + * If main.signal is non-zero, then this handles the following signals: + * - F_signal_abort + * - F_signal_broken_pipe + * - F_signal_hangup + * - F_signal_interrupt + * - F_signal_quit + * - F_signal_termination + * + * @param main + * The program and settings data. + * + * Must be of type kt_tacocat_main_t. + * + * @return + * 0, always. + * + * @see f_thread_cancel_state_set() + * + * @see kt_tacocat_signal_handler() + */ +#if !defined(_di_kt_tacocat_thread_signal_) && !defined(_di_thread_support_) + extern void * kt_tacocat_thread_signal(void * const main); +#endif // !defined(_di_kt_tacocat_thread_signal_) && !defined(_di_thread_support_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_thread_h -- 1.8.3.1