1 /* 2 * types.h 3 * 4 * Version: 2.2.5 5 * 6 * ----------------------------------------------------------------------------- 7 * 8 * SPDX-License-Identifier: MIT 9 * 10 * Copyright (c) 2018-2024 Ryan M. Lederman <lederman@gmail.com> 11 * Copyright (c) 2018-2024 Jeffrey H. Johnson <trnsz@pobox.com> 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a copy of 14 * this software and associated documentation files (the "Software"), to deal in 15 * the Software without restriction, including without limitation the rights to 16 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 17 * the Software, and to permit persons to whom the Software is furnished to do so, 18 * subject to the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included in all 21 * copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 25 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 27 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 * 30 * ----------------------------------------------------------------------------- 31 */ 32 33 #ifndef _SIR_TYPES_H_INCLUDED 34 # define _SIR_TYPES_H_INCLUDED 35 36 # include "sir/platform.h" 37 # include "sir/config.h" 38 # include "sir/ansimacros.h" 39 40 /** 41 * @addtogroup public 42 * @{ 43 * 44 * @defgroup publictypes Types 45 * @{ 46 */ 47 48 /** Log file identifier type. */ 49 typedef uint32_t sirfileid; 50 51 /** Plugin module identifier type. */ 52 typedef uint32_t sirpluginid; 53 54 /* 55 * The following define the available levels of logging output. 56 */ 57 58 # define SIRL_NONE 0x0000U /**< No output. */ 59 # define SIRL_EMERG 0x0001U /**< Nuclear war, Armageddon, etc. */ 60 # define SIRL_ALERT 0x0002U /**< Action required ASAP. */ 61 # define SIRL_CRIT 0x0004U /**< Critical errors. */ 62 # define SIRL_ERROR 0x0008U /**< Errors. */ 63 # define SIRL_WARN 0x0010U /**< Warnings that could likely be ignored. */ 64 # define SIRL_NOTICE 0x0020U /**< Normal but significant. */ 65 # define SIRL_INFO 0x0040U /**< Informational messages. */ 66 # define SIRL_DEBUG 0x0080U /**< Debugging/diagnostic output. */ 67 # define SIRL_ALL 0x00ffU /**< Include all logging levels. */ 68 # define SIRL_DEFAULT 0x0100U /**< Default levels for this type of destination. */ 69 70 /** The ::sir_level type. */ 71 typedef uint16_t sir_level; 72 73 /** ::sir_level bitmask type. */ 74 typedef uint16_t sir_levels; 75 76 /* 77 * Formatting options for a destination. 78 */ 79 80 # define SIRO_ALL 0x00000000U /**< Include all formatting and functionality. */ 81 # define SIRO_NOTIME 0x00000100U /**< Exclude time stamps (implies ::SIRO_NOMSEC). */ 82 # define SIRO_NOMSEC 0x00000200U /**< Exclude millisecond-resolution in time stamps. */ 83 # define SIRO_NOHOST 0x00000400U /**< Exclude local hostname. */ 84 # define SIRO_NOLEVEL 0x00000800U /**< Exclude human-readable logging level. */ 85 # define SIRO_NONAME 0x00001000U /**< Exclude process/app name. */ 86 # define SIRO_NOPID 0x00002000U /**< Exclude process ID. */ 87 # define SIRO_NOTID 0x00004000U /**< Exclude thread ID/name. */ 88 # define SIRO_NOHDR 0x00010000U /**< Don't write header messages to log files. */ 89 # define SIRO_MSGONLY 0x00007f00U /**< Sets all other options except ::SIRO_NOHDR. */ 90 # define SIRO_DEFAULT 0x00100000U /**< Default options for this type of destination. */ 91 92 /** The ::sir_option type. */ 93 typedef uint32_t sir_option; 94 95 /** ::sir_option bitmask type. */ 96 typedef uint32_t sir_options; 97 98 /** Color mode selection. */ 99 typedef enum { 100 SIRCM_16 = 0, /**< 4-bit 16-color mode. */ 101 SIRCM_256 = 1, /**< 8-bit 256-color mode. */ 102 SIRCM_RGB = 2, /**< 24-bit RGB-color mode. */ 103 SIRCM_INVALID = 3 /**< Represents the invalid color mode. */ 104 } sir_colormode; 105 106 /** Attributes for stdio output. */ 107 typedef enum { 108 SIRTA_NORMAL = 0, /**< Normal text. */ 109 SIRTA_BOLD = 1, /**< Bold text. */ 110 SIRTA_DIM = 2, /**< Dimmed text. */ 111 SIRTA_EMPH = 3, /**< Italicized/emphasized text. */ 112 SIRTA_ULINE = 4, /**< Underlined text. */ 113 } sir_textattr; 114 115 /** Colors for stdio output (16-color mode). */ 116 enum { 117 /* 4-bit (16-color). */ 118 SIRTC_BLACK = 0, /**< Black. */ 119 SIRTC_RED = 1, /**< Red. */ 120 SIRTC_GREEN = 2, /**< Green. */ 121 SIRTC_YELLOW = 3, /**< Yellow. */ 122 SIRTC_BLUE = 4, /**< Blue. */ 123 SIRTC_MAGENTA = 5, /**< Magenta. */ 124 SIRTC_CYAN = 6, /**< Cyan. */ 125 SIRTC_LGRAY = 7, /**< Light gray. */ 126 SIRTC_DGRAY = 8, /**< Dark gray. */ 127 SIRTC_BRED = 9, /**< Bright red. */ 128 SIRTC_BGREEN = 10, /**< Bright green. */ 129 SIRTC_BYELLOW = 11, /**< Bright yellow. */ 130 SIRTC_BBLUE = 12, /**< Bright blue. */ 131 SIRTC_BMAGENTA = 13, /**< Bright magenta. */ 132 SIRTC_BCYAN = 14, /**< Bright cyan. */ 133 SIRTC_WHITE = 15, /**< White. */ 134 /* 8-bit (256-color) and 24-bit (RGB color) modes: 135 * use the numeric representation (16..255) instead of an enum. 136 * these colors do not have defined names like the above. */ 137 SIRTC_DEFAULT = 256 /**< Represents the default color. */ 138 }; 139 140 /** stdio text color type. */ 141 typedef uint32_t sir_textcolor; 142 143 /** 144 * @struct sir_errorinfo 145 * @brief Information about an error that occurred. 146 * 147 * Granular error information in order to provide the caller with flexibility in 148 * regards to error handling and formatting. 149 */ 150 typedef struct { 151 const char* func; /**< Name of the function in which the error occurred. */ 152 const char* file; /**< Name of the file in which the error occurred. */ 153 uint32_t line; /**< Line number at which the error occurred. */ 154 int os_code; /**< If an OS/libc error, the relevant code. */ 155 char os_msg[SIR_MAXERROR]; /**< If an OS/libc error, the relevant message. */ 156 uint16_t code; /**< Numeric error code (see ::sir_errorcode). */ 157 char msg[SIR_MAXERROR]; /**< Error message associated with code. */ 158 } sir_errorinfo; 159 160 /** 161 * @struct sir_textstyle 162 * @brief Container for all the information associated with the appearance of text 163 * in the context of stdio. 164 * 165 * For 4-bit (16-color) and 8-bit (256-color) modes, fg and bg are simply the 166 * associated SIRTC_* value. For 24-bit RGB color mode, fg and bg are packed as 167 * follows: 0x00rrggbb. 168 */ 169 typedef struct { 170 sir_textattr attr; /**< Text attributes. */ 171 sir_textcolor fg; /**< Foreground color. */ 172 sir_textcolor bg; /**< Background color. */ 173 } sir_textstyle; 174 175 /** 176 * @struct sir_stdio_dest 177 * @brief Configuration for stdio destinations (stdout and stderr). 178 * 179 * @see ::sir_syslog_dest 180 */ 181 typedef struct { 182 /** ::sir_level bitmask defining output levels to register for. */ 183 sir_levels levels; 184 185 /** ::sir_option bitmask defining the formatting of output. */ 186 sir_options opts; 187 } sir_stdio_dest; 188 189 /** 190 * @struct sir_syslog_dest 191 * @brief Configuration for the system logger destination. 192 * 193 * @see ::sir_stdio_dest 194 */ 195 typedef struct { 196 sir_levels levels; /**< ::sir_level bitmask defining levels to register for. */ 197 198 /** 199 * ::sir_option bitmask defining the formatting of output. 200 * 201 * @remark Unlike the stdio and log file destinations, not all options are 202 * supported. This is due to the fact that system logging facilities typically 203 * already include the information represented by ::sir_option on their own. 204 * 205 * Furthermore, the supported options vary based on the system logging 206 * facility in use. 207 * 208 * @note If your system supports syslog, and libsir is compiled with the intent 209 * to use it (SIR_SYSLOG_ENABLED is defined), then at least SIRO_NOPID is 210 * supported. 211 */ 212 sir_options opts; 213 214 /** Reserved for internal use; do not modify. */ 215 struct { 216 uint32_t mask; /**< State bitmask. */ 217 void* logger; /**< System logger handle/identifier. */ 218 } _state; 219 220 /** 221 * The identity string to pass to the system logger. 222 * @see ::sir_syslogid 223 */ 224 char identity[SIR_MAX_SYSLOG_ID]; 225 226 /** 227 * The category string to pass to the system logger. 228 * @see ::sir_syslogcat 229 */ 230 char category[SIR_MAX_SYSLOG_CAT]; 231 } sir_syslog_dest; 232 233 /** 234 * @struct sirinit 235 * @brief libsir initialization and configuration data. 236 * 237 * @note Pass a pointer to an instance of this structure to ::sir_init 238 * to begin using libsir. 239 * 240 * @see ::sir_makeinit 241 * @see ::sir_stdio_dest 242 * @see ::sir_syslog_dest 243 */ 244 typedef struct { 245 sir_stdio_dest d_stdout; /**< stdout configuration. */ 246 sir_stdio_dest d_stderr; /**< stderr configuration. */ 247 sir_syslog_dest d_syslog; /**< System logger configuration. */ 248 249 /** 250 * The name to use in log messages (usually the process name). Set ::SIRO_NONAME 251 * in a destination's options bitmask to suppress it. 252 */ 253 char name[SIR_MAXNAME]; 254 } sirinit; 255 256 /** 257 * @} 258 * @} 259 */ 260 261 /** Magic number used to determine if libsir has been initialized. */ 262 # define _SIR_MAGIC 0x60906090U 263 264 /** System logger facility state flags. */ 265 # define SIRSL_IS_OPEN 0x00000001U /**< Log is open. */ 266 # define SIRSL_LEVELS 0x00000002U /**< Level registrations. */ 267 # define SIRSL_OPTIONS 0x00000004U /**< Formatting options. */ 268 # define SIRSL_CATEGORY 0x00000008U /**< Category. */ 269 # define SIRSL_IDENTITY 0x00000010U /**< Identity. */ 270 # define SIRSL_UPDATED 0x00000020U /**< Config has been updated. */ 271 # define SIRSL_IS_INIT 0x00000040U /**< Subsystem is initialized. */ 272 273 # if defined(__WIN__) 274 /** Invalid parameter handler used when passing possibly invalid values to 275 * certain Windows libc calls. Without it, the default behavior is to abort. */ 276 typedef void (*invalparamfn)(const wchar_t*, const wchar_t*, const wchar_t*, 277 unsigned int, uintptr_t); 278 # endif 279 280 /** Internally-used time value type. */ 281 typedef struct { 282 # if !defined(__WIN__) 283 time_t sec; 284 long msec; 285 # else /* __WIN__ */ 286 LARGE_INTEGER counter; 287 # endif 288 } sir_time; 289 290 /** Internally-used global config container. */ 291 typedef struct { 292 sirinit si; 293 struct { 294 char hostname[SIR_MAXHOST]; 295 time_t last_hname_chk; 296 char pidbuf[SIR_MAXPID]; 297 pid_t pid; 298 char timestamp[SIR_MAXTIME]; 299 300 /** Spam squelch state data. */ 301 struct { 302 bool squelch; 303 uint64_t hash; 304 char prefix[2]; 305 sir_level level; 306 size_t counter; 307 size_t threshold; 308 } last; 309 } state; 310 } sirconfig; 311 312 /** Internally-used log file data. */ 313 typedef struct { 314 const char* path; 315 sir_levels levels; 316 sir_options opts; 317 FILE* f; 318 sirfileid id; 319 int writes_since_size_chk; 320 } sirfile; 321 322 /** Log file cache. */ 323 typedef struct { 324 sirfile* files[SIR_MAXFILES]; 325 size_t count; 326 } sirfcache; 327 328 /** The libsir-to-plugin query data structure. */ 329 typedef struct { 330 uint8_t iface_ver; /**< Plugin interface version. */ 331 uint8_t maj_ver; /**< Major version number. */ 332 uint8_t min_ver; /**< Minor version number. */ 333 uint8_t bld_ver; /**< Build/patch version number. */ 334 sir_levels levels; /**< Level registration bitmask. */ 335 sir_options opts; /**< Formatting options bitmask. */ 336 const char* author; /**< Plugin author information. */ 337 const char* desc; /**< Plugin description. */ 338 uint64_t caps; /**< Plugin capabilities bitmask. */ 339 } sir_plugininfo; 340 341 /** Plugin versioning. */ 342 # define SIR_PLUGIN_V1 1 343 # define SIR_PLUGIN_VCURRENT SIR_PLUGIN_V1 344 345 /** Plugin export names for v1. */ 346 # define SIR_PLUGIN_EXPORT_QUERY "sir_plugin_query" 347 # define SIR_PLUGIN_EXPORT_INIT "sir_plugin_init" 348 # define SIR_PLUGIN_EXPORT_WRITE "sir_plugin_write" 349 # define SIR_PLUGIN_EXPORT_CLEANUP "sir_plugin_cleanup" 350 351 /** Plugin export typedefs for v1. */ 352 typedef bool (*sir_plugin_queryfn)(sir_plugininfo*); 353 typedef bool (*sir_plugin_initfn)(void); 354 typedef bool (*sir_plugin_writefn)(sir_level, const char*); 355 typedef bool (*sir_plugin_cleanupfn)(void); 356 357 /** Plugin interface for v1. */ 358 typedef struct { 359 sir_plugin_queryfn query; /**< Address of sir_plugin_query. */ 360 sir_plugin_initfn init; /**< Address of sir_plugin_init. */ 361 sir_plugin_writefn write; /**< Address of sir_plugin_write. */ 362 sir_plugin_cleanupfn cleanup; /**< Address of sir_plugin_cleanup. */ 363 } sir_pluginifacev1; 364 365 typedef sir_pluginifacev1 sir_pluginiface; 366 367 /** Internally-used plugin module data. */ 368 typedef struct { 369 const char* path; 370 sir_pluginhandle handle; 371 sir_plugininfo info; 372 bool loaded; 373 bool valid; 374 sir_pluginiface iface; 375 sirpluginid id; 376 } sir_plugin; 377 378 /** Plugin module cache. */ 379 typedef struct { 380 sir_plugin* plugins[SIR_MAXPLUGINS]; 381 size_t count; 382 } sir_plugincache; 383 384 /** A node in a sir_queue. */ 385 typedef struct _sir_queue_node { 386 struct _sir_queue_node* next; 387 void* data; 388 } sir_queue_node; 389 390 /** FIFO queue. */ 391 typedef struct { 392 sir_queue_node* head; /**< The first node in the linked list. */ 393 } sir_queue; 394 395 /** Job used by a job queue. */ 396 typedef struct { 397 bool (*fn)(void*); /**< Callback to be executed as part of the job. */ 398 void* data; /**< Data to pass to the callback. */ 399 } sir_threadpool_job; 400 401 /** Thread pool/job queue data container. */ 402 typedef struct { 403 sir_thread* threads; /**< A list of thread handles. */ 404 size_t num_threads; /**< The number of threads in the pool. */ 405 sir_queue* jobs; /**< A queue of jobs to run (FIFO). */ 406 sir_condition cond; /**< A condition which indicates that a job is ready. */ 407 sir_mutex mutex; /**< A mutex to be paired with the condition variable. */ 408 bool cancel; /**< Causes threads in the pool to exit when true. */ 409 } sir_threadpool; 410 411 /** Formatted output container. */ 412 typedef struct { 413 char style[SIR_MAXSTYLE]; 414 char* timestamp; 415 char msec[SIR_MAXMSEC]; 416 const char* hostname; 417 const char* pid; 418 const char* level; 419 const char* name; 420 char tid[SIR_MAXPID]; 421 char message[SIR_MAXMESSAGE]; 422 char output[SIR_MAXOUTPUT]; 423 size_t output_len; 424 } sirbuf; 425 426 /** ::sir_level <-> ::sir_textstyle mapping. */ 427 typedef struct { 428 const sir_level level; /**< The level for which the style applies. */ 429 sir_textstyle style; /**< The un-formatted representation. */ 430 char str[SIR_MAXSTYLE]; /**< The formatted string representation. */ 431 } sir_level_style_tuple; 432 433 /** Container for text style related data that is mutex protected. */ 434 typedef struct { 435 sir_level_style_tuple* map; 436 sir_colormode* color_mode; 437 } sir_text_style_data; 438 439 /** ::sir_level <-> human-readable string form. */ 440 typedef struct { 441 const sir_level level; /**< The level for which the string applies. */ 442 const char* fmt; /**< The formatted string representation. */ 443 } sir_level_str_pair; 444 445 /** Mutex <-> protected section mapping. */ 446 typedef enum { 447 SIRMI_CONFIG = 0, /**< The ::sirconfig section. */ 448 SIRMI_FILECACHE, /**< The ::sirfcache section. */ 449 SIRMI_PLUGINCACHE, /**< The ::sir_plugincache section. */ 450 # if !defined(SIR_NO_TEXT_STYLING) 451 SIRMI_TEXTSTYLE, /**< The ::sir_level_style_tuple section. */ 452 # endif 453 } sir_mutex_id; 454 455 /** Per-thread error type. */ 456 typedef struct { 457 uint32_t lasterror; 458 int os_code; 459 char os_msg[SIR_MAXERROR]; 460 461 struct { 462 const char* func; 463 const char* file; 464 uint32_t line; 465 } loc; 466 } sir_thread_err; 467 468 /** Bitmask defining which values are to be updated in the global config. */ 469 typedef uint32_t sir_config_data_field; 470 471 # define SIRU_LEVELS 0x00000001U /**< Update level registrations. */ 472 # define SIRU_OPTIONS 0x00000002U /**< Update formatting options. */ 473 # define SIRU_SYSLOG_ID 0x00000004U /**< Update system logger identity. */ 474 # define SIRU_SYSLOG_CAT 0x00000008U /**< Update system logger category. */ 475 # define SIRU_ALL 0x0000000fU /**< Update all available fields. */ 476 477 /** Encapsulates dynamic updating of current configuration. */ 478 typedef struct { 479 uint32_t fields; /**< ::sir_config_data_field bitmask. */ 480 sir_levels* levels; /**< Level registrations. */ 481 sir_options* opts; /**< Formatting options. */ 482 const char* sl_identity; /**< System logger identity. */ 483 const char* sl_category; /**< System logger category. */ 484 } sir_update_config_data; 485 486 #endif /* !_SIR_TYPES_H_INCLUDED */