1 #ifndef SRC_LOG_H_
2 #define SRC_LOG_H_
3 
4 #include <errno.h>
5 #include <string.h>
6 #include <stdbool.h>
7 #include "incidence/incidence.h"
8 
9 /*
10  * According to BSD style, __dead is supposed to be defined in sys/cdefs.h,
11  * but it doesn't exist in Linux.
12  */
13 #ifndef __dead
14 #if __GNUC__
15 #define __dead __attribute__((noreturn))
16 #else
17 #define __dead /* Nothing */
18 #endif
19 #endif
20 
21 /*
22  * I know that the OpenBSD style guide says that we shouldn't declare our own
23  * error printing functions, but we kind of need to do it:
24  *
25  * - It's convoluted to use err() and warn() on libcrypto errors.
26  * - I was tasked with using syslog anyway, but the API is kind of limited
27  *   (especially since vsyslog() is not portable.)
28  * - We want to transparently always print offending file name.
29  */
30 
31 #if __GNUC__
32 #define CHECK_FORMAT(str, args) __attribute__((format(printf, str, args)))
33 #else
34 /*
35  * No idea how this looks in other compilers.
36  * It's safe to obviate since we're bound to see the warnings every time we use
37  * GCC anyway.
38  */
39 #define CHECK_FORMAT(str, args) /* Nothing */
40 #endif
41 
42 /*
43  * Only call this group of functions when you know there's only one thread.
44  *
45  * log_setup() is an incomplete initialization meant to be called when the
46  * program starts. Logging can be performed after log_setup(), but it will use
47  * default values.
48  * log_init() finishes initialization by loading the user's intended config.
49  * log_teardown() reverts initialization.
50  */
51 int log_setup(bool);
52 void log_start(void);
53 void log_teardown(void);
54 
55 /* Call to flush the stdout/stderr streams */
56 void log_flush(void);
57 
58 /*
59  * Check if corresponding logging is enabled. You can use these to short-circuit
60  * out of heavy logging code.
61  */
62 bool log_val_enabled(unsigned int level);
63 bool log_op_enabled(unsigned int level);
64 
65 /* == Operation logs == */
66 
67 /* Status reports of no interest to the user. */
68 void pr_op_debug(const char *, ...) CHECK_FORMAT(1, 2);
69 /* Status reports likely useful to the user. */
70 void pr_op_info(const char *, ...) CHECK_FORMAT(1, 2);
71 /* Non-errors that suggest a problem. */
72 int pr_op_warn(const char *, ...) CHECK_FORMAT(1, 2);
73 /* Do not use this; see pr_op_err() and pr_op_errno(). */
74 int __pr_op_err(int, const char *, ...) CHECK_FORMAT(2, 3);
75 /*
76  * Problematic situations that prevent Fort from doing its job.
77  * (Always returns -EINVAL.)
78  */
79 #define pr_op_err(fmt, ...) __pr_op_err(-EINVAL, fmt, ##__VA_ARGS__)
80 /*
81  * Like pr_op_err(), but also prints strerror(error).
82  * (Always returns error).
83  */
84 #define pr_op_errno(error, fmt, ...) \
85 	__pr_op_err(error, fmt ": %s", ##__VA_ARGS__, strerror(abs(error)))
86 /* Like pr_op_err(), except it prints libcrypto's error stack as well. */
87 int op_crypto_err(const char *, ...) CHECK_FORMAT(1, 2);
88 
89 
90 /* == Validation logs == */
91 
92 /* Status reports of no interest to the user. */
93 void pr_val_debug(const char *, ...) CHECK_FORMAT(1, 2);
94 /* Status reports likely useful to the user. */
95 void pr_val_info(const char *, ...) CHECK_FORMAT(1, 2);
96 /* Issues that did not trigger RPKI object rejection. */
97 int pr_val_warn(const char *, ...) CHECK_FORMAT(1, 2);
98 /* Do not use this; see pr_val_err() and pr_val_errno(). */
99 int __pr_val_err(int, const char *, ...) CHECK_FORMAT(2, 3);
100 /* Problems that trigger RPKI object rejection. */
101 #define pr_val_err(fmt, ...) __pr_val_err(-EINVAL, fmt, ##__VA_ARGS__)
102 /*
103  * Like pr_val_err(), but also prints strerror(error).
104  * (Always returns error).
105  */
106 #define pr_val_errno(error, fmt, ...) \
107 	__pr_val_err(error, fmt ": %s", ##__VA_ARGS__, strerror(abs(error)))
108 /* Like pr_val_err(), except it prints libcrypto's error stack as well. */
109 int val_crypto_err(const char *, ...) CHECK_FORMAT(1, 2);
110 
111 /* Like pr_*_err(), specific to out-of-memory situations. */
112 int pr_enomem(void);
113 /* Programming errors */
114 __dead void pr_crit(const char *, ...) CHECK_FORMAT(1, 2);
115 
116 int incidence(enum incidence_id, const char *, ...) CHECK_FORMAT(2, 3);
117 
118 /*
119  * Quick and dirty debugging messages.
120  *
121  * These are not meant to be uploaded; remember to delete them once the bug has
122  * been found.
123  */
124 #define DBG_COLOR "\x1B[32m" /* Green */
125 #define DBG_COLOR_RESET "\x1B[0m"
126 #define PR_DEBUG \
127     printf(DBG_COLOR "%s:%d (%s())" DBG_COLOR_RESET "\n", \
128     __FILE__, __LINE__, __func__)
129 #define PR_DEBUG_MSG(msg, ...) \
130     printf(DBG_COLOR "%s:%d (%s()): " msg DBG_COLOR_RESET "\n", \
131     __FILE__, __LINE__, __func__, ##__VA_ARGS__)
132 
133 #endif /* SRC_LOG_H_ */
134