The GPGME is not really that good.
It calls the user space GNUPG program `gpg`.
This is clunky and nasty.
The project also handles memory poorly.
Thanks to utilizing it, the `tacocat` now exists with reachable memory.
```
==17190== HEAP SUMMARY:
==17190== in use at exit: 1,189 bytes in 39 blocks
==17190== total heap usage: 124 allocs, 85 frees, 42,076 bytes allocated
```
I should look into other projects as well once I get GPGME fully setup and working.
Projects like libgit2 or even trying to directly use libgcrypt.
# fss-0000
_di_thread_support_ Disable thread support, handling signals without using a separate thread.
+
+_en_gpgme_support_ Enable use of GPGME for providing encryption during message transfer.
+
_kt_resolve_default_kevux_ Default to Kevux DNS resolution methods rather than classic DNS resolution methods.
# - fanalyzer: Compile using GCC's -fanalyzer compile time option.
# - flex_arrays: Use GCC strict flex arrays (supported by GCC version 13 or greater).
# - gcc: Use GCC specific settings.
+# - gpgme: Enable the use of GPGME.
# - 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.
version_file micro
version_target minor
-modes android clang coverage debug fanalyzer flex_arrays gcc individual individual_thread level monolithic pinephone test thread threadless
-modes_default debug gcc monolithic thread
+modes android clang coverage debug fanalyzer flex_arrays gcc gpgme individual individual_thread level monolithic pinephone test thread threadless
+modes_default debug gcc gpgme monolithic thread
build_compiler gcc
build_compiler-clang clang
build_libraries_shared-individual_thread -lf_thread
build_libraries_shared-level -lfll_2 -lfll_1 -lfll_0
build_libraries_shared-monolithic -lfll
+build_libraries_shared-gpgme -lgpgme -lassuan -lgpg-error
build_libraries_static -l:libc.a
build_libraries_static-individual -l:libfll_error.a -l:libfll_fss.a -l:libfll_print.a -l:libfll_program.a
build_libraries_static-individual_thread -l:libf_thread.a
build_libraries_static-level -l:libfll_2.a -l:libfll_1.a -l:libfll_0.a
build_libraries_static-monolithic -l:libfll.a
+build_libraries_static-gpgme -l:libgpgme.a -l:libassuan.a -l:libgpg-error.a
build_sources_headers common.h common/define.h common/enumeration.h common/string.h common/type.h
build_sources_headers print/error.h print/message.h print/verbose.h print/warning.h
build_sources_headers receive/step/check.h receive/step/control.h receive/step/done.h receive/step/extract.h receive/step/find.h receive/step/next.h receive/step/packet.h receive/step/write.h
build_sources_headers send/step/build.h send/step/check.h send/step/done.h send/step/encode.h send/step/file.h send/step/header.h send/step/packet.h send/step/size.h send/step/wait.h
+build_sources_headers-gpgme gpgme.h print/gpgme.h
+
build_sources_library common.c common/define.c common/enumeration.c common/string.c common/type.c
build_sources_library print/error.c print/message.c print/verbose.c print/warning.c
build_sources_library packet.c process.c receive.c send.c signal.c tacocat.c thread.c
build_sources_library receive/step/check.c receive/step/control.c receive/step/done.c receive/step/extract.c receive/step/find.c receive/step/next.c receive/step/packet.c receive/step/write.c
build_sources_library send/step/build.c send/step/check.c send/step/done.c send/step/encode.c send/step/file.c send/step/header.c send/step/packet.c send/step/size.c send/step/wait.c
+build_sources_library-gpgme gpgme.c print/gpgme.c
+
build_sources_documentation man
build_static no
defines -D_libcap_legacy_only_
defines-android -D_di_f_thread_attribute_affinity_get_ -D_di_f_thread_attribute_affinity_set_ -D_di_f_thread_attribute_concurrency_get_ -D_di_f_thread_attribute_concurrency_set_ -D_di_f_thread_attribute_default_get_ -D_di_f_thread_attribute_default_set_ -D_di_f_thread_cancel_test_ -D_di_f_thread_join_try_ -D_di_f_thread_join_timed_ -D_pthread_mutex_prioceiling_unsupported_ -D_di_f_thread_semaphore_file_close_ -D_di_f_thread_semaphore_file_open_ -D_di_f_thread_semaphore_file_delete_ -D_di_f_thread_cancel_type_set_ -D_di_f_thread_mutex_consistent_ -D_di_f_thread_mutex_attribute_robust_get_ -D_di_f_thread_mutex_attribute_robust_set_ -D_pthread_kill_as_pthread_cancel_
defines-clang -D_clang_not_a_compile_time_constant_workaround_
+defines-gpgme -D_en_gpgme_support_
defines-pinephone -D_di_f_thread_mutex_priority_ceiling_get_ -D_di_f_thread_mutex_priority_ceiling_set_ -D_di_f_thread_mutex_attribute_priority_ceiling_get_ -D_di_f_thread_mutex_attribute_priority_ceiling_set_
defines-threadless -D_di_thread_support_
defines-thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_
# - fanalyzer: Compile using GCC's -fanalyzer compile time option.
# - flex_arrays: Use GCC strict flex arrays (supported by GCC version 13 or greater).
# - gcc: Use GCC specific settings.
+# - gpgme: Enable the use of GPGME.
# - 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.
version_file micro
version_target minor
-modes android clang coverage debug fanalyzer flex_arrays gcc individual individual_thread level monolithic pinephone test thread threadless
-modes_default debug gcc monolithic thread
+modes android clang coverage debug fanalyzer flex_arrays gcc gpgme individual individual_thread level monolithic pinephone test thread threadless
+modes_default debug gcc gpgme monolithic thread
build_compiler gcc
build_compiler-clang clang
build_libraries_shared-individual_thread -lf_thread
build_libraries_shared-level -lfll_2 -lfll_1 -lfll_0
build_libraries_shared-monolithic -lfll
+build_libraries_shared-gpgme -lgpgme -lassuan -lgpg-error
build_libraries_static -l:libc.a -l:libtacocat.a
build_libraries_static-individual -l:libfll_error.a -l:libfll_fss.a -l:libfll_print.a -l:libfll_program.a
build_libraries_static-individual_thread -l:libf_thread.a
build_libraries_static-level -l:libfll_2.a -l:libfll_1.a -l:libfll_0.a
build_libraries_static-monolithic -l:libfll.a
+build_libraries_static-gpgme -l:libgpgme.a -l:libassuan.a -l:libgpg-error.a
build_sources_headers tacocat.h string.h
defines-android -D_di_f_thread_attribute_affinity_get_ -D_di_f_thread_attribute_affinity_set_ -D_di_f_thread_attribute_concurrency_get_ -D_di_f_thread_attribute_concurrency_set_ -D_di_f_thread_attribute_default_get_ -D_di_f_thread_attribute_default_set_ -D_di_f_thread_cancel_test_ -D_di_f_thread_join_try_ -D_di_f_thread_join_timed_ -D_pthread_mutex_prioceiling_unsupported_ -D_di_f_thread_semaphore_file_close_ -D_di_f_thread_semaphore_file_open_ -D_di_f_thread_semaphore_file_delete_ -D_di_f_thread_cancel_type_set_ -D_di_f_thread_mutex_consistent_ -D_di_f_thread_mutex_attribute_robust_get_ -D_di_f_thread_mutex_attribute_robust_set_ -D_pthread_kill_as_pthread_cancel_
defines-clang -D_clang_not_a_compile_time_constant_workaround_
defines-debug -D_en_f_status_debug_
+defines-gpgme -D_en_gpgme_support_
defines-pinephone -D_di_f_thread_mutex_priority_ceiling_get_ -D_di_f_thread_mutex_priority_ceiling_set_ -D_di_f_thread_mutex_attribute_priority_ceiling_get_ -D_di_f_thread_mutex_attribute_priority_ceiling_set_
defines-threadless -D_di_thread_support_
defines-thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_
* kt_tacocat_main_flag_*_d:
* - none: No flags set.
* - copyright: Print copyright.
+ * - encrypt: Enable encryption (such as GPGME).
* - headers: Print headers on send or receive.
* - help: Print help.
* - max_buffer: When set, a maximum buffer on receive is enforced.
#ifndef _di_kt_tacocat_main_flag_d_
#define kt_tacocat_main_flag_none_d 0x0
#define kt_tacocat_main_flag_copyright_d 0x1
- #define kt_tacocat_main_flag_headers_d 0x2
- #define kt_tacocat_main_flag_help_d 0x4
- #define kt_tacocat_main_flag_max_buffer_d 0x8
- #define kt_tacocat_main_flag_receive_d 0x10
- #define kt_tacocat_main_flag_resolve_classic_d 0x20
- #define kt_tacocat_main_flag_resolve_kevux_d 0x40
- #define kt_tacocat_main_flag_send_d 0x80
- #define kt_tacocat_main_flag_version_d 0x100
- #define kt_tacocat_main_flag_version_copyright_help_d 0x105
+ #define kt_tacocat_main_flag_encrypt_d 0x2
+ #define kt_tacocat_main_flag_headers_d 0x4
+ #define kt_tacocat_main_flag_help_d 0x8
+ #define kt_tacocat_main_flag_max_buffer_d 0x10
+ #define kt_tacocat_main_flag_receive_d 0x20
+ #define kt_tacocat_main_flag_resolve_classic_d 0x40
+ #define kt_tacocat_main_flag_resolve_kevux_d 0x80
+ #define kt_tacocat_main_flag_send_d 0x100
+ #define kt_tacocat_main_flag_version_d 0x200
+ #define kt_tacocat_main_flag_version_copyright_help_d 0x209
#endif // _di_kt_tacocat_main_flag_d_
/**
}
#endif // _di_kt_tacocat_setting_delete_
+#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_delete_)
+ void kt_tacocat_gpgme_delete(kt_tacocat_gpgme_t * const gpgme) {
+
+ if (!gpgme) return;
+
+ gpgme_release(gpgme->control);
+
+ // @todo
+
+ gpgme->version = f_string_empty_s.string;
+ }
+#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_delete_)
+
#ifndef _di_kt_tacocat_socket_sets_delete_callback_
f_status_t kt_tacocat_socket_sets_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) {
/**
* A set of all socket related properties.
*
- * size_block: The size in bytes to used to represent a block when sending or receiving packets.
- * size_done: The size in bytes that are done being processed (generally used by send/write).
- * size_total: The size in bytes tht represent the entire size to be processed (size_done should eventually equal this).
- *
- * flag: A set of flags.
- * step: The current step the socket set is operating under (this is either a send or receive step define depending on whether or not flag has the send bit set).
- * retry: The current number of retries performed.
- * part: The current active part number.
- * port: The current port number for the socket.
- *
- * file: The file structure.
- * socket: Socket structure.
- * status: The status of the socket operations.
- *
- * range: A generic range, often used for FSS processing.
- * objects: An array of FSS Objects.
- * objects_header: An array of FSS Objects, for the Header section.
- * objects_signature: An array of FSS Objects, for the Signature section.
- * contents: An array of FSS Contents.
- * contents_header: An array of FSS Contents, for the Header section.
- * contents_signature: An array of FSS Contents, for the Signature section.
- * objects_delimits: An array of FSS Object delimits.
- * objects_delimits_header: An array of FSS Object delimits, for the Header section.
- * objects_delimits_signature: An array of FSS Object delimits, for the Signature section.
- * contents_delimits: An array of FSS Content delimits.
- * contents_delimits_header: An array of FSS Content delimits, for the Header section.
- * contents_delimits_signature: An array of FSS Content delimits, for the Signature section.
- * parts: An array of numbers where each index represents a part number.
- * objects_quoted_header: An array of FSS Objects quoted flags, for the Header section.
- * objects_quoted_signature: An array of FSS Objects quoted flags, for the Header section.
- * contents_quoted_header: An array of FSS Content quoted flags, for the Header section.
- * contents_quoted_signature: An array of FSS Content quoted flags, for the Header section.
- * comments: An array of FSS comments.
- * state: Basic state information, usually passed to the FSS functions.
- *
- * as: A custom name to use for the file rather than the actual file name.
- * buffer: A buffer for sending or receiving data between clients.
- * cache: A cache used for various purposes, but primarily for the building of the send packet.
- * client: A single client address for some network connection.
- * header: A buffer used for the header part and possibly the reset of a packet, except for the actual payload.
- * id: The identifier.
- * name: A file name for reading from or writing to.
- * network: A network name for the socket.
- * time: A representation of time added for informative purposes to the packet (in a human friendly format).
- * packet: The simple packet range representing the parts of the packet for use during processing.
- * write_state: State data for the packet write operation.
- *
- * abstruses: The abstruse header map array, used for building the headers when sending a response.
- * headers: The map of the headers after being processed for use when buulding the headers when sending a response.
+ * Properties:
+ * - size_block: The size in bytes to used to represent a block when sending or receiving packets.
+ * - size_done: The size in bytes that are done being processed (generally used by send/write).
+ * - size_total: The size in bytes tht represent the entire size to be processed (size_done should eventually equal this).
+ *
+ * - flag: A set of flags.
+ * - step: The current step the socket set is operating under (this is either a send or receive step define depending on whether or not flag has the send bit set).
+ * - retry: The current number of retries performed.
+ * - part: The current active part number.
+ * - port: The current port number for the socket.
+ *
+ * - file: The file structure.
+ * - socket: Socket structure.
+ * - status: The status of the socket operations.
+ *
+ * - range: A generic range, often used for FSS processing.
+ * - objects: An array of FSS Objects.
+ * - objects_header: An array of FSS Objects, for the Header section.
+ * - objects_signature: An array of FSS Objects, for the Signature section.
+ * - contents: An array of FSS Contents.
+ * - contents_header: An array of FSS Contents, for the Header section.
+ * - contents_signature: An array of FSS Contents, for the Signature section.
+ * - objects_delimits: An array of FSS Object delimits.
+ * - objects_delimits_header: An array of FSS Object delimits, for the Header section.
+ * - objects_delimits_signature: An array of FSS Object delimits, for the Signature section.
+ * - contents_delimits: An array of FSS Content delimits.
+ * - contents_delimits_header: An array of FSS Content delimits, for the Header section.
+ * - contents_delimits_signature: An array of FSS Content delimits, for the Signature section.
+ * - parts: An array of numbers where each index represents a part number.
+ * - objects_quoted_header: An array of FSS Objects quoted flags, for the Header section.
+ * - objects_quoted_signature: An array of FSS Objects quoted flags, for the Header section.
+ * - contents_quoted_header: An array of FSS Content quoted flags, for the Header section.
+ * - contents_quoted_signature: An array of FSS Content quoted flags, for the Header section.
+ * - comments: An array of FSS comments.
+ * - state: Basic state information, usually passed to the FSS functions.
+ *
+ * - as: A custom name to use for the file rather than the actual file name.
+ * - buffer: A buffer for sending or receiving data between clients.
+ * - cache: A cache used for various purposes, but primarily for the building of the send packet.
+ * - client: A single client address for some network connection.
+ * - header: A buffer used for the header part and possibly the reset of a packet, except for the actual payload.
+ * - id: The identifier.
+ * - name: A file name for reading from or writing to.
+ * - network: A network name for the socket.
+ * - time: A representation of time added for informative purposes to the packet (in a human friendly format).
+ * - packet: The simple packet range representing the parts of the packet for use during processing.
+ * - write_state: State data for the packet write operation.
+ *
+ * - abstruses: The abstruse header map array, used for building the headers when sending a response.
+ * - headers: The map of the headers after being processed for use when buulding the headers when sending a response.
*/
#ifndef _di_kt_tacocat_socket_set_t_
typedef struct {
/**
* An array of socket sets.
*
- * array: The array of socket sets.
- * used: Total number of allocated spaces used.
- * size: Total amount of allocated space.
+ * Properties:
+ * - array: The array of socket sets.
+ * - used: Total number of allocated spaces used.
+ * - size: Total amount of allocated space.
*/
#ifndef _di_kt_tacocat_socket_sets_t_
typedef struct {
* 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.
- * interval: The poll interval to use.
- * interval_fast: A poll interval to use when needing the interval to be short.
- * max_buffer: The maximum buffer size to use on receive.
- * active_receive: The number of active receive processes, after initial connection is established.
- * active_send: The number of active send processes, after initial connection is established.
+ * Properties:
+ * - flag: Flags passed to the main function.
+ * - interval: The poll interval to use.
+ * - interval_fast: A poll interval to use when needing the interval to be short.
+ * - max_buffer: The maximum buffer size to use on receive.
+ * - active_receive: The number of active receive processes, after initial connection is established.
+ * - active_send: The number of active send processes, after initial connection is established.
*
- * status_receive: A status used exclusively by the receive thread.
- * status_send: A status used exclusively by the send thread.
+ * - status_receive: A status used exclusively by the receive thread.
+ * - status_send: A status used exclusively by the send thread.
*
- * state: The state data used when processing data.
+ * - state: The state data used when processing data.
*
- * receive_polls: An array of sockets to poll for receiving data, specifically for passing to f_file_poll().
- * send_polls: An array of sockets to poll for sending data, specifically for passing to f_file_poll().
+ * - receive_polls: An array of sockets to poll for receiving data, specifically for passing to f_file_poll().
+ * - send_polls: An array of sockets to poll for sending data, specifically for passing to f_file_poll().
*
- * receive: The socket set for receiving data receive clients.
- * send: The socket set for sending data send clients.
+ * - receive: The socket set for receiving data receive clients.
+ * - send: The socket set for sending data send clients.
*/
#ifndef _di_kt_tacocat_setting_t_
typedef struct {
/**
* The TacocaT caches.
*
- * peek: A static cache intended to be used for performing a peek on a given network stream.
+ * Properties:
+ * - peek: A static cache intended to be used for performing a peek on a given network stream.
*
- * buffer: A string buffer used for caching purposes.
+ * - buffer: A string buffer used for caching purposes.
*/
#ifndef _di_kt_tacocat_cache_t_
typedef struct {
/**
* The TacocaT callbacks.
*
- * setting_load_send_receive: Process loading the settings regarding send and receive, handling DNS resolution and file opening as needed.
+ * Properties:
+ * - setting_load_send_receive: Process loading the settings regarding send and receive, handling DNS resolution and file opening as needed.
*/
#ifndef _di_kt_tacocat_call_t_
typedef struct {
/**
* The main thread settings.
+ *
+ * Properties:
+ * - id_receive: The receive identifier.
+ * - id_send: The send identifier.
*/
#ifndef _di_kt_tacocat_thread_t_
typedef struct {
#endif // _di_kt_tacocat_thread_t_
/**
+ * The GPGME data.
+ *
+ * Properties:
+ * - control: The GPGME control data.
+ * - data: The GPGME regular data.
+ * - engine: The GPGME engine inforrmation data.
+ * - error: The GPGME error data.
+ *
+ * - version: The GPGME reported version.
+ */
+#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_t_)
+ typedef struct {
+ gpgme_ctx_t control;
+ gpgme_data_t data;
+ gpgme_engine_info_t engine;
+ gpgme_error_t error;
+
+ f_string_constant_t version;
+ } kt_tacocat_gpgme_t;
+
+ #define kt_tacocat_gpgme_t_initialize { \
+ .control = 0, \
+ .data = 0, \
+ .engine = 0, \
+ .error = 0, \
+ .version = f_string_empty_s.string, \
+ }
+#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_t_)
+
+/**
* The main program data as a single structure.
*
- * program: The main program data.
+ * Properties:
+ * - program: The main program data.
+ *
+ * - cache: The program cache.
+ * - call: The program call backs.
+ * - setting: The settings data.
+ * - thread: The program thread data.
*
- * cache: The program cache.
- * call: The program call backs.
- * setting: The settings data.
- * thread: The program thread data.
+ * - gpgme: The GPGME data, if supported.
*/
#ifndef _di_kt_tacocat_main_t_
struct kt_tacocat_main_t_ {
kt_tacocat_call_t call;
kt_tacocat_setting_t setting;
kt_tacocat_thread_t thread;
+
+ #ifdef _en_gpgme_support_
+ kt_tacocat_gpgme_t gpgme;
+ #endif // _en_gpgme_support_
};
- #define kt_tacocat_main_t_initialize { \
- .program = fll_program_data_t_initialize, \
- .cache = kt_tacocat_cache_t_initialize, \
- .call = kt_tacocat_call_t_initialize, \
- .setting = kt_tacocat_setting_t_initialize, \
- .thread = kt_tacocat_thread_t_initialize, \
- }
+ #ifdef _en_gpgme_support_
+ #define kt_tacocat_main_t_initialize { \
+ .program = fll_program_data_t_initialize, \
+ .cache = kt_tacocat_cache_t_initialize, \
+ .call = kt_tacocat_call_t_initialize, \
+ .setting = kt_tacocat_setting_t_initialize, \
+ .thread = kt_tacocat_thread_t_initialize, \
+ .gpgme = kt_tacocat_gpgme_t_initialize, \
+ }
+ #else
+ #define kt_tacocat_main_t_initialize { \
+ .program = fll_program_data_t_initialize, \
+ .cache = kt_tacocat_cache_t_initialize, \
+ .call = kt_tacocat_call_t_initialize, \
+ .setting = kt_tacocat_setting_t_initialize, \
+ .thread = kt_tacocat_thread_t_initialize, \
+ }
+ #endif // _en_gpgme_support_
#endif // _di_kt_tacocat_main_t_
/**
#endif // _di_kt_tacocat_setting_delete_
/**
+ * Delete the gpgme data.
+ *
+ * @param gpgme
+ * The gpgme data.
+ *
+ * Must not be NULL.
+ */
+#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_delete_)
+ extern void kt_tacocat_gpgme_delete(kt_tacocat_gpgme_t * const gpgme);
+#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_delete_)
+
+/**
* A call back intended to be passed to f_memory_arrays_resize() for an kt_tacocat_socket_sets_t structure.
*
* This is only called when shrinking the array and generally should perform deallocations.
--- /dev/null
+#include "tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_setup_)
+ void kt_tacocat_gpgme_setup(kt_tacocat_main_t * const main) {
+
+ if (!main) return;
+
+ kt_tacocat_gpgme_t * const gpgme = &main->gpgme;
+
+ gpgme->version = gpgme_check_version(0);
+
+ gpgme->error = gpgme_new(&gpgme->control);
+
+ if (gpgme->error) {
+ main->setting.state.status = F_status_set_error(F_failure);
+
+ kt_tacocat_print_gpgme_error(&main->program.error, F_status_debug_source_d);
+
+ return;
+ }
+
+ gpgme->error = gpgme_engine_check_version(GPGME_PROTOCOL_OPENPGP);
+
+ if (gpgme->error) {
+ main->setting.state.status = F_status_set_error(F_failure);
+
+ kt_tacocat_print_gpgme_error(&main->program.error, F_status_debug_source_d);
+
+ return;
+ }
+
+ main->setting.state.status = F_okay;
+ }
+#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_setup_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _kt_tacocat_main_gpgme_h
+#define _kt_tacocat_main_gpgme_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform GPGME setup.
+ *
+ * For available GPGME protocols, see: https://www.gnupg.org/documentation/manuals/gpgme/Protocols-and-Engines.html .
+ *
+ * For GPGME signal handling, see: https://www.gnupg.org/documentation/manuals/gpgme/Signal-Handling.html .
+ * > If you do install a signal handler for SIGPIPE, you must be prepared to handle any SIGPIPE events that occur due to GPGME writing to a defunct pipe.
+ * > Furthermore, if your application is multi-threaded, and you install a signal action for SIGPIPE, you must make sure you do this either before gpgme_check_version is called or afterwards.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This does not alter main.setting.state.status, except on interrupt signal.
+ *
+ * Must not be NULL.
+ *
+ * This alters set.status:
+ * F_okay on success.
+ *
+ * F_failure (with error bit) on gpgme_check_version() error.
+ *
+ * @see gpgme_check_version()
+ */
+#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_setup_)
+ extern void kt_tacocat_gpgme_setup(kt_tacocat_main_t * const main);
+#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_setup_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_main_gpgme_h
fl_print_format("%[%QNetwork error on%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
- fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QFile '%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[' for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[' for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[ for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[ for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
fl_print_format("%[', the maximum size is%] ", print->to, print->set->error, print->set->error);
fl_print_format("%[%ul%]", print->to, print->set->notable, size_expect, print->set->notable);
fl_print_format("%[%QNetwork on%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
fl_print_format("%[' is busy.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QNetwork on%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
- fl_print_format("%[' failed to receive data or write to file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' failed to receive data or write to file '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QNetwork on%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
- fl_print_format("%[' failed to send data or read from file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' failed to send data or read from file '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QNetwork packet header on%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
- fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
- fl_print_format("%[' is invalid for Object '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' is invalid for Object '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->set->notable, buffer, object, print->set->notable);
- fl_print_format("%[' and Content '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' and Content '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->set->notable, buffer, content, print->set->notable);
- fl_print_format("%[' with a status code of %]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' with a status code of %]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_ul_single_s.string, print->to, print->set->notable, F_status_set_fine(status), print->set->notable);
fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QNetwork packet is invalid for%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
if (name.used) {
- fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
}
fl_print_format("%[%QMax retry on failure reached while trying to%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, kt_tacocat_receive_s, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, set->network, print->set->notable);
- fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, set->name, print->set->notable);
fl_print_format("%['", print->to, print->set->error);
fl_print_format("%[%QMax retry on failure reached while trying to%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, kt_tacocat_send_s, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, set->network, print->set->notable);
- fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' with file '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, set->name, print->set->notable);
fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QNetwork on%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
fl_print_format("%[', the received packet is too large (expecting%] ", print->to, print->set->error, print->set->error);
fl_print_format("%[%ul%]", print->to, print->set->notable, size_expect, print->set->notable);
- fl_print_format(" %[bytes but instead got%] ", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[bytes but instead got%] ", print->to, print->set->error, print->set->error);
fl_print_format("%[%ul%]", print->to, print->set->notable, size_got, print->set->notable);
fl_print_format("%[ bytes).%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QNetwork on%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
- fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
fl_print_format("%[', the received packet is too small (expecting%] ", print->to, print->set->error, print->set->error);
fl_print_format("%[%ul%]", print->to, print->set->notable, size_expect, print->set->notable);
- fl_print_format(" %[bytes but instead got%] ", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[bytes but instead got%] ", print->to, print->set->error, print->set->error);
fl_print_format("%[%ul%]", print->to, print->set->notable, size_got, print->set->notable);
fl_print_format("%[ bytes).%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QThe parameter%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_QQ_single_s.string, 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(" %[may only be either '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, 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("%' or '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, kt_tacocat_kevux_s, print->set->notable);
- fl_print_format(" %[' but '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[' but '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, unknown, print->set->notable);
fl_print_format("%[' is given.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QUnknown or invalid port number%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format(f_string_format_Q_range_single_s.string, print->to, print->set->notable, address, range, print->set->notable);
- fl_print_format(" %[from the address '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[from the address '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, address, print->set->notable);
fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format("%[%QUnsupported protocol%] ", print->to, print->set->error, print->prefix, print->set->error);
fl_print_format("%[%ul%]", print->to, print->set->notable, protocol, print->set->notable);
- fl_print_format(" %[while processing '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(" %[while processing '%]", print->to, print->set->error, print->set->error);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
--- /dev/null
+#include "../tacocat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_tacocat_print_gpgme_error_
+ f_status_t kt_tacocat_print_gpgme_error(fl_print_t * const print, const f_string_t debug) {
+
+ if (!print || !print->custom) return F_status_set_error(F_output_not);
+ if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+ kt_tacocat_main_t * const main = (kt_tacocat_main_t *) print->custom;
+
+ f_file_stream_lock(print->to);
+
+ fl_print_format("%[%QGPGME error:%] ", print->to, print->set->error, print->prefix, print->set->error);
+ fl_print_format(f_string_format_S_single_s.string, print->to, print->set->notable, gpgme_strerror(main->gpgme.error), print->set->notable);
+ fl_print_format(" %[(%]", print->to, print->set->error, print->set->error);
+ fl_print_format(f_string_format_S_single_s.string, print->to, print->set->notable, gpgme_strsource(main->gpgme.error), print->set->notable);
+ fl_print_format("%[)", print->to, print->set->error);
+
+ if (debug && *debug) {
+ fl_print_format(macro_fll_error_s(019_debug_open), print->to, print->context);
+ fl_print_format(f_string_format_S_single_s.string, print->to, print->notable, debug, print->notable);
+ fl_print_format(macro_fll_error_s(020_debug_close), print->to, print->context);
+ }
+
+ fl_print_format(".%]%r", print->to, print->context, f_string_eol_s);
+
+
+ f_file_stream_unlock(print->to);
+
+ return F_okay;
+ }
+#endif // _di_kt_tacocat_print_gpgme_error_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * Kevux Tools - TacocaT
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the print gpgme functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_tacocat_print_gpgme_h
+#define _kt_tacocat_print_gpgme_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print GPGME related error message regarding some failure.
+ *
+ * @param print
+ * The output structure to print to.
+ *
+ * This requires print.custom to be fake_main_t.
+ *
+ * Must not be NULL.
+ *
+ * This does not alter print.custom.setting.state.status.
+ * @param debug
+ * (optional) The debug details, such as file, line number, and function.
+ *
+ * Set to NULL to disable.
+ *
+ * @return
+ * F_okay on success.
+ * F_output_not on success, but no printing is performed.
+ *
+ * F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_print()
+ */
+#ifndef _di_kt_tacocat_print_gpgme_error_
+ extern f_status_t kt_tacocat_print_gpgme_error(fl_print_t * const print, const f_string_t debug);
+#endif // _di_kt_tacocat_print_gpgme_error_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_tacocat_print_gpgme_h
if (F_status_is_error(kt_tacocat_process_socket_set_error_has(main, kt_tacocat_long_receive_s, main->setting.receive, &main->setting.status_receive))) return;
if (F_status_is_error(kt_tacocat_process_socket_set_error_has(main, kt_tacocat_long_send_s, main->setting.send, &main->setting.status_send))) return;
+ #ifdef _en_gpgme_support_
+ if (main->setting.flag & kt_tacocat_main_flag_encrypt_d) {
+ kt_tacocat_gpgme_setup(main);
+ if (F_status_is_error(main->setting.state.status)) return;
+ }
+ #endif // _en_gpgme_support_
+
#ifdef _di_thread_support_
// @todo implement fork and wait for both receive and send.
#else
if (F_status_is_error_not(main->setting.state.status)) {
main->setting.state.status = F_okay;
}
+
+ #ifdef _en_gpgme_support_
+ kt_tacocat_gpgme_delete(&main->gpgme);
+ #endif // _en_gpgme_support_
}
#endif // _di_kt_tacocat_process_main_
#include <time.h>
#include <unistd.h>
+// Other includes.
+#ifdef _en_gpgme_support_
+ #include <gpgme.h>
+#endif // _en_gpgme_support_
+
// FLL-0 includes.
#include <fll/level_0/type.h>
#include <fll/level_0/status.h>
#include <program/kevux/tools/tacocat/main/signal.h>
#include <program/kevux/tools/tacocat/main/thread.h>
+#ifdef _en_gpgme_support_
+ #include <program/kevux/tools/tacocat/main/gpgme.h>
+ #include <program/kevux/tools/tacocat/main/print/gpgme.h>
+#endif // _en_gpgme_support_
+
#ifdef __cplusplus
extern "C" {
#endif
data.call.setting_load_send_receive = kt_tacocat_setting_load_send_receive;
+ #ifdef _en_gpgme_support_
+ data.setting.flag |= kt_tacocat_main_flag_encrypt_d;
+ #else
+ data.setting.flag &= ~kt_tacocat_main_flag_encrypt_d;
+ #endif // _en_gpgme_support_
+
if (f_pipe_input_exists()) {
data.program.pipe = fll_program_data_pipe_input_e;
}