1 #ifndef SIEVE_ERROR_H
2 #define SIEVE_ERROR_H
3 
4 #include "lib.h"
5 #include "compat.h"
6 
7 #include <stdarg.h>
8 
9 /*
10  * Forward declarations
11  */
12 
13 struct var_expand_table;
14 
15 struct sieve_instance;
16 struct sieve_script;
17 struct sieve_error_handler;
18 
19 /*
20  * Types
21  */
22 
23 enum sieve_error_flags {
24 	SIEVE_ERROR_FLAG_GLOBAL = (1 << 0),
25 	SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO = (1 << 1),
26 };
27 
28 struct sieve_error_params {
29 	enum log_type log_type;
30 	struct event *event;
31 
32 	/* Location log command in C source code */
33 	struct {
34 		const char *filename;
35 		unsigned int linenum;
36 	} csrc;
37 
38 	/* Location in Sieve source script */
39 	const char *location;
40 };
41 
42 /*
43  * Utility
44  */
45 
46 /* Converts external messages to a style that better matches Sieve user errors
47  */
48 const char *sieve_error_from_external(const char *msg);
49 
50 /*
51  * Global (user+system) errors
52  */
53 
54 void sieve_global_logv(struct sieve_instance *svinst,
55 		       struct sieve_error_handler *ehandler,
56 		       const struct sieve_error_params *params,
57 		       const char *fmt, va_list args) ATTR_FORMAT(4, 0);
58 void sieve_global_info_logv(struct sieve_instance *svinst,
59 			    struct sieve_error_handler *ehandler,
60 			    const struct sieve_error_params *params,
61 			    const char *fmt, va_list args) ATTR_FORMAT(4, 0);
62 
63 void sieve_global_error(struct sieve_instance *svinst,
64 			struct sieve_error_handler *ehandler,
65 			const char *csrc_filename,
66 			unsigned int csrc_linenum,
67 			const char *location, const char *fmt, ...)
68 			ATTR_FORMAT(6, 7);
69 #define sieve_global_error(svinst, ehandler, ...) \
70 	sieve_global_error(svinst, ehandler, __FILE__, __LINE__, __VA_ARGS__)
71 void sieve_global_warning(struct sieve_instance *svinst,
72 			  struct sieve_error_handler *ehandler,
73 			  const char *csrc_filename,
74 			  unsigned int csrc_linenum,
75 			  const char *location, const char *fmt, ...)
76 			  ATTR_FORMAT(6, 7);
77 #define sieve_global_warning(svinst, ehandler, ...) \
78 	sieve_global_warning(svinst, ehandler, __FILE__, __LINE__, __VA_ARGS__)
79 void sieve_global_info(struct sieve_instance *svinst,
80 		       struct sieve_error_handler *ehandler,
81 		       const char *csrc_filename,
82 		       unsigned int csrc_linenum,
83 		       const char *location, const char *fmt, ...)
84 		       ATTR_FORMAT(6, 7);
85 #define sieve_global_info(svinst, ehandler, ...) \
86 	sieve_global_info(svinst, ehandler, __FILE__, __LINE__, __VA_ARGS__)
87 void sieve_global_info_error(struct sieve_instance *svinst,
88 			     struct sieve_error_handler *ehandler,
89 			     const char *csrc_filename,
90 			     unsigned int csrc_linenum,
91 			     const char *location, const char *fmt, ...)
92 			     ATTR_FORMAT(6, 7);
93 #define sieve_global_info_error(svinst, ehandler, ...) \
94 	sieve_global_info_error(svinst, ehandler, __FILE__, __LINE__, \
95 				__VA_ARGS__)
96 void sieve_global_info_warning(struct sieve_instance *svinst,
97 			       struct sieve_error_handler *ehandler,
98 			       const char *csrc_filename,
99 			       unsigned int csrc_linenum,
100 			       const char *location, const char *fmt, ...)
101 			       ATTR_FORMAT(6, 7);
102 #define sieve_global_info_warning(svinst, ehandler, ...) \
103 	sieve_global_info_warning(svinst, ehandler, __FILE__, __LINE__, \
104 				  __VA_ARGS__)
105 
106 /*
107  * Main (user) error functions
108  */
109 
110 /* For these functions it is the responsibility of the caller to
111  * manage the datastack.
112  */
113 
114 const char *
115 sieve_error_script_location(const struct sieve_script *script,
116 			    unsigned int source_line);
117 
118 void sieve_logv(struct sieve_error_handler *ehandler,
119 		const struct sieve_error_params *params,
120 		const char *fmt, va_list args) ATTR_FORMAT(3, 0);
121 
122 void sieve_event_logv(struct sieve_instance *svinst,
123 		      struct sieve_error_handler *ehandler,
124 		      struct event *event, enum log_type log_type,
125 		      const char *csrc_filename, unsigned int csrc_linenum,
126 		      const char *location, enum sieve_error_flags flags,
127 		      const char *fmt, va_list args) ATTR_FORMAT(9, 0);
128 void sieve_event_log(struct sieve_instance *svinst,
129 		     struct sieve_error_handler *ehandler,
130 		     struct event *event, enum log_type log_type,
131 		     const char *csrc_filename, unsigned int csrc_linenum,
132 		     const char *location, enum sieve_error_flags flags,
133 		     const char *fmt, ...) ATTR_FORMAT(9, 10);
134 #define sieve_event_log(svinst, ehandler, event, log_type, ...) \
135 	sieve_event_log(svinst, ehandler, event, log_type, __FILE__, __LINE__, \
136 			__VA_ARGS__)
137 
138 void sieve_criticalv(struct sieve_instance *svinst,
139 		     struct sieve_error_handler *ehandler,
140 		     const struct sieve_error_params *params,
141 		     const char *user_prefix, const char *fmt, va_list args)
142 		     ATTR_FORMAT(5, 0);
143 
144 void sieve_error(struct sieve_error_handler *ehandler,
145 		 const char *csrc_filename, unsigned int csrc_linenum,
146 		 const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6);
147 #define sieve_error(ehandler, ...) \
148 	sieve_error(ehandler, __FILE__, __LINE__, __VA_ARGS__)
149 void sieve_warning(struct sieve_error_handler *ehandler,
150 		   const char *csrc_filename, unsigned int csrc_linenum,
151 		   const char *location, const char *fmt, ...)
152 		   ATTR_FORMAT(5, 6);
153 #define sieve_warning(ehandler, ...) \
154 	sieve_warning(ehandler, __FILE__, __LINE__, __VA_ARGS__)
155 void sieve_info(struct sieve_error_handler *ehandler,
156 		const char *csrc_filename, unsigned int csrc_linenum,
157 		const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6);
158 #define sieve_info(ehandler, ...) \
159 	sieve_info(ehandler, __FILE__, __LINE__, __VA_ARGS__)
160 void sieve_debug(struct sieve_error_handler *ehandler,
161 		 const char *csrc_filename, unsigned int csrc_linenum,
162 		 const char *location, const char *fmt, ...) ATTR_FORMAT(5, 6);
163 #define sieve_debug(ehandler, ...) \
164 	sieve_debug(ehandler, __FILE__, __LINE__, __VA_ARGS__)
165 void sieve_critical(struct sieve_instance *svinst,
166 		    struct sieve_error_handler *ehandler,
167 		    const char *csrc_filename, unsigned int csrc_linenum,
168 		    const char *location, const char *user_prefix,
169 		    const char *fmt, ...) ATTR_FORMAT(7, 8);
170 #define sieve_critical(svinst, ehandler, ...) \
171 	sieve_critical(svinst, ehandler, __FILE__, __LINE__, __VA_ARGS__)
172 
173 
174 void sieve_internal_error_params(struct sieve_error_handler *ehandler,
175 				 const struct sieve_error_params *params,
176 				 const char *user_prefix);
177 void sieve_internal_error(struct sieve_error_handler *ehandler,
178 			  const char *csrc_filename, unsigned int csrc_linenum,
179 			  const char *location, const char *user_prefix)
180 			  ATTR_NULL(1, 4, 5);
181 #define sieve_internal_error(ehandler, ...) \
182 	sieve_internal_error(ehandler, __FILE__, __LINE__, __VA_ARGS__)
183 
184 /*
185  * Error handler configuration
186  */
187 
188 void sieve_error_handler_accept_infolog(struct sieve_error_handler *ehandler,
189 					bool enable);
190 void sieve_error_handler_accept_debuglog(struct sieve_error_handler *ehandler,
191 					 bool enable);
192 
193 /*
194  * Error handler statistics
195  */
196 
197 unsigned int sieve_get_errors(struct sieve_error_handler *ehandler);
198 unsigned int sieve_get_warnings(struct sieve_error_handler *ehandler);
199 
200 bool sieve_errors_more_allowed(struct sieve_error_handler *ehandler);
201 
202 /*
203  * Error handler object
204  */
205 
206 void sieve_error_handler_ref(struct sieve_error_handler *ehandler);
207 void sieve_error_handler_unref(struct sieve_error_handler **ehandler);
208 
209 void sieve_error_handler_reset(struct sieve_error_handler *ehandler);
210 
211 /*
212  * Error handlers
213  */
214 
215 /* Write errors to dovecot master log */
216 struct sieve_error_handler *
217 sieve_master_ehandler_create(struct sieve_instance *svinst,
218 			     unsigned int max_errors);
219 
220 /* Write errors to stderr */
221 struct sieve_error_handler *
222 sieve_stderr_ehandler_create(struct sieve_instance *svinst,
223 			     unsigned int max_errors);
224 
225 /* Write errors into a string buffer */
226 struct sieve_error_handler *
227 sieve_strbuf_ehandler_create(struct sieve_instance *svinst, string_t *strbuf,
228 			     bool crlf, unsigned int max_errors);
229 
230 /* Write errors to a logfile */
231 struct sieve_error_handler *
232 sieve_logfile_ehandler_create(struct sieve_instance *svinst,
233 			      const char *logfile, unsigned int max_errors);
234 
235 #endif
236