3dd890a00fd1feefa27cbb2cc257456737315f71
[exim.git] / src / src / functions.h
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* Copyright (c) The Exim Maintainers 2020 - 2021 */
7 /* See the file NOTICE for conditions of use and distribution. */
8
9
10 /* Prototypes for functions that appear in various modules. Gathered together
11 to avoid having a lot of tiddly little headers with only a couple of lines in
12 them. However, some functions that are used (or not used) by utility programs
13 are in in fact in separate headers. */
14 #ifndef _FUNCTIONS_H_
15 #define _FUNCTIONS_H_
16
17 #include <ctype.h>
18 #include <sys/time.h>
19
20
21 #ifdef EXIM_PERL
22 extern gstring *call_perl_cat(gstring *, uschar **, uschar *,
23                  uschar **) WARN_UNUSED_RESULT;
24 extern void    cleanup_perl(void);
25 extern uschar *init_perl(uschar *);
26 #endif
27
28
29 #ifndef DISABLE_TLS
30 extern const char *
31                std_dh_prime_default(void);
32 extern const char *
33                std_dh_prime_named(const uschar *);
34
35 extern uschar * tls_cert_crl_uri(void *, uschar * mod);
36 extern uschar * tls_cert_ext_by_oid(void *, uschar *, int);
37 extern uschar * tls_cert_issuer(void *, uschar * mod);
38 extern uschar * tls_cert_not_before(void *, uschar * mod);
39 extern uschar * tls_cert_not_after(void *, uschar * mod);
40 extern uschar * tls_cert_ocsp_uri(void *, uschar * mod);
41 extern uschar * tls_cert_serial_number(void *, uschar * mod);
42 extern uschar * tls_cert_signature(void *, uschar * mod);
43 extern uschar * tls_cert_signature_algorithm(void *, uschar * mod);
44 extern uschar * tls_cert_subject(void *, uschar * mod);
45 extern uschar * tls_cert_subject_altname(void *, uschar * mod);
46 extern uschar * tls_cert_version(void *, uschar * mod);
47
48 extern uschar * tls_cert_der_b64(void * cert);
49 extern uschar * tls_cert_fprt_md5(void *);
50 extern uschar * tls_cert_fprt_sha1(void *);
51 extern uschar * tls_cert_fprt_sha256(void *);
52
53 extern void    tls_clean_env(void);
54 extern BOOL    tls_client_start(client_conn_ctx *, smtp_connect_args *,
55                   void *, tls_support *, uschar **);
56 extern void    tls_client_creds_reload(BOOL);
57
58 extern void    tls_close(void *, int);
59 extern BOOL    tls_could_read(void);
60 extern void    tls_daemon_init(void);
61 extern int     tls_daemon_tick(void);
62 extern BOOL    tls_dropprivs_validate_require_cipher(BOOL);
63 extern BOOL    tls_export_cert(uschar *, size_t, void *);
64 extern int     tls_feof(void);
65 extern int     tls_ferror(void);
66 extern uschar *tls_field_from_dn(uschar *, const uschar *);
67 extern void    tls_free_cert(void **);
68 extern int     tls_getc(unsigned);
69 extern uschar *tls_getbuf(unsigned *);
70 extern void    tls_get_cache(unsigned);
71 extern BOOL    tls_hasc(void);
72 extern BOOL    tls_import_cert(const uschar *, void **);
73 extern BOOL    tls_is_name_for_cert(const uschar *, void *);
74 # ifdef USE_OPENSSL
75 extern BOOL    tls_openssl_options_parse(uschar *, long *);
76 # endif
77 extern int     tls_read(void *, uschar *, size_t);
78 extern int     tls_server_start(uschar **);
79 extern void    tls_shutdown_wr(void *);
80 extern BOOL    tls_smtp_buffered(void);
81 extern int     tls_ungetc(int);
82 #if defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT)
83 extern void    tls_watch_discard_event(int);
84 extern void    tls_watch_invalidate(void);
85 #endif
86 extern int     tls_write(void *, const uschar *, size_t, BOOL);
87 extern uschar *tls_validate_require_cipher(void);
88 extern void    tls_version_report(FILE *);
89
90 # ifdef SUPPORT_DANE
91 extern int     tlsa_lookup(const host_item *, dns_answer *, BOOL);
92 # endif
93
94 #endif  /*DISABLE_TLS*/
95
96
97 /* Everything else... */
98
99 extern acl_block *acl_read(uschar *(*)(void), uschar **);
100 extern int     acl_check(int, uschar *, uschar *, uschar **, uschar **);
101 extern int     acl_eval(int, uschar *, uschar **, uschar **);
102
103 extern tree_node *acl_var_create(uschar *);
104 extern void    acl_var_write(uschar *, uschar *, void *);
105
106 #ifdef EXPERIMENTAL_ARC
107 extern void   *arc_ams_setup_sign_bodyhash(void);
108 extern const uschar *arc_header_feed(gstring *, BOOL);
109 extern gstring *arc_sign(const uschar *, gstring *, uschar **);
110 extern void     arc_sign_init(void);
111 extern const uschar *acl_verify_arc(void);
112 extern uschar * fn_arc_domains(void);
113 #endif
114
115 extern void    assert_no_variables(void *, int, const char *, int);
116 extern int     auth_call_pam(const uschar *, uschar **);
117 extern int     auth_call_pwcheck(uschar *, uschar **);
118 extern int     auth_call_radius(const uschar *, uschar **);
119 extern int     auth_call_saslauthd(const uschar *, const uschar *,
120                  const uschar *, const uschar *, uschar **);
121 extern int     auth_check_serv_cond(auth_instance *);
122 extern int     auth_check_some_cond(auth_instance *, uschar *, uschar *, int);
123 extern int     auth_client_item(void *, auth_instance *, const uschar **,
124                  unsigned, int, uschar *, int);
125
126
127 extern int     auth_get_data(uschar **, const uschar *, int);
128 extern int     auth_get_no64_data(uschar **, uschar *);
129 extern int     auth_prompt(const uschar *);
130 extern int     auth_read_input(const uschar *);
131 extern gstring * auth_show_supported(gstring *);
132 extern uschar *auth_xtextencode(uschar *, int);
133 extern int     auth_xtextdecode(uschar *, uschar **);
134
135 #ifdef EXPERIMENTAL_ARC
136 extern gstring *authres_arc(gstring *);
137 #endif
138 #ifndef DISABLE_DKIM
139 extern gstring *authres_dkim(gstring *);
140 #endif
141 #ifdef SUPPORT_DMARC
142 extern gstring *authres_dmarc(gstring *);
143 #endif
144 extern gstring *authres_smtpauth(gstring *);
145 #ifdef SUPPORT_SPF
146 extern gstring *authres_spf(gstring *);
147 #endif
148
149 extern uschar *b64encode(const uschar *, int);
150 extern uschar *b64encode_taint(const uschar *, int, BOOL);
151 extern int     b64decode(const uschar *, uschar **);
152 extern int     bdat_getc(unsigned);
153 extern uschar *bdat_getbuf(unsigned *);
154 extern BOOL    bdat_hasc(void);
155 extern int     bdat_ungetc(int);
156 extern void    bdat_flush_data(void);
157
158 extern void    bits_clear(unsigned int *, size_t, int *);
159 extern void    bits_set(unsigned int *, size_t, int *);
160
161 extern void    cancel_cutthrough_connection(BOOL, const uschar *);
162 extern gstring *cat_file(FILE *, gstring *, uschar *);
163 extern gstring *cat_file_tls(void *, gstring *, uschar *);
164 extern int     check_host(void *, const uschar *, const uschar **, uschar **);
165 extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
166 extern pid_t   child_open_exim_function(int *, const uschar *);
167 extern pid_t   child_open_exim2_function(int *, uschar *, uschar *,
168                  const uschar *);
169 extern pid_t   child_open_function(uschar **, uschar **, int,
170                  int *, int *, BOOL, const uschar *);
171 extern pid_t   child_open_uid(const uschar **, const uschar **, int,
172                  uid_t *, gid_t *, int *, int *, uschar *, BOOL, const uschar *);
173 extern BOOL    cleanup_environment(void);
174 extern void    cutthrough_data_puts(uschar *, int);
175 extern void    cutthrough_data_put_nl(void);
176 extern uschar *cutthrough_finaldot(void);
177 extern BOOL    cutthrough_flush_send(void);
178 extern BOOL    cutthrough_headers_send(void);
179 extern BOOL    cutthrough_predata(void);
180 extern void    release_cutthrough_connection(const uschar *);
181
182 extern void    daemon_go(void);
183
184 #ifdef EXPERIMENTAL_DCC
185 extern int     dcc_process(uschar **);
186 #endif
187
188 extern void    debug_logging_activate(uschar *, uschar *);
189 extern void    debug_logging_stop(void);
190 extern void    debug_print_argv(const uschar **);
191 extern void    debug_print_ids(uschar *);
192 extern void    debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2);
193 extern void    debug_print_string(uschar *);
194 extern void    debug_print_tree(const char *, tree_node *);
195 extern void    debug_vprintf(int, const char *, va_list);
196 extern void    debug_print_socket(int);
197
198 extern void    decode_bits(unsigned int *, size_t, int *,
199                    uschar *, bit_table *, int, uschar *, int);
200 extern void    delete_pid_file(void);
201 extern void    deliver_local(address_item *, BOOL);
202 extern address_item *deliver_make_addr(uschar *, BOOL);
203 extern void    delivery_log(int, address_item *, int, uschar *);
204 extern int     deliver_message(uschar *, BOOL, BOOL);
205 extern void    deliver_msglog(const char *, ...) PRINTF_FUNCTION(1,2);
206 extern void    deliver_set_expansions(address_item *);
207 extern int     deliver_split_address(address_item *);
208 extern void    deliver_succeeded(address_item *);
209
210 extern void    delivery_re_exec(int);
211
212 extern void    die_tainted(const uschar *, const uschar *, int);
213 extern BOOL    directory_make(const uschar *, const uschar *, int, BOOL);
214 #ifndef DISABLE_DKIM
215 extern uschar *dkim_exim_query_dns_txt(const uschar *);
216 extern void    dkim_exim_sign_init(void);
217
218 extern BOOL    dkim_transport_write_message(transport_ctx *,
219                   struct ob_dkim *, const uschar ** errstr);
220 #endif
221 extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
222 extern int     dns_basic_lookup(dns_answer *, const uschar *, int);
223 extern uschar *dns_build_reverse(const uschar *);
224 extern time_t  dns_expire_from_soa(dns_answer *, int);
225 extern void    dns_init(BOOL, BOOL, BOOL);
226 extern BOOL    dns_is_aa(const dns_answer *);
227 extern BOOL    dns_is_secure(const dns_answer *);
228 extern int     dns_lookup(dns_answer *, const uschar *, int, const uschar **);
229 extern void    dns_pattern_init(void);
230 extern int     dns_special_lookup(dns_answer *, const uschar *, int, const uschar **);
231 extern dns_record *dns_next_rr(const dns_answer *, dns_scan *, int);
232 extern uschar *dns_text_type(int);
233 extern void    dscp_list_to_stream(FILE *);
234 extern BOOL    dscp_lookup(const uschar *, int, int *, int *, int *);
235
236 extern void    enq_end(uschar *);
237 extern BOOL    enq_start(uschar *, unsigned);
238 #ifndef DISABLE_EVENT
239 extern uschar *event_raise(uschar *, const uschar *, uschar *);
240 extern void    msg_event_raise(const uschar *, const address_item *);
241 #endif
242
243 extern int     exim_chown_failure(int, const uschar*, uid_t, gid_t);
244 extern const uschar * exim_errstr(int);
245 extern void    exim_exit(int) NORETURN;
246 extern void    exim_gettime(struct timeval *);
247 extern void    exim_nullstd(void);
248 extern void    exim_setugid(uid_t, gid_t, BOOL, uschar *);
249 extern void    exim_underbar_exit(int) NORETURN;
250 extern void    exim_wait_tick(struct timeval *, int);
251 extern int     exp_bool(address_item *addr,
252   uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue,
253   uschar *svalue, BOOL *rvalue);
254 extern BOOL    expand_check_condition(uschar *, uschar *, uschar *);
255 extern uschar *expand_file_big_buffer(const uschar *);
256 extern uschar *expand_string(uschar *); /* public, cannot make const */
257 extern const uschar *expand_cstring(const uschar *); /* ... so use this one */
258 extern uschar *expand_getkeyed(const uschar *, const uschar *);
259
260 extern uschar *expand_hide_passwords(uschar * );
261 extern uschar *expand_string_copy(const uschar *);
262 extern int_eximarith_t expand_string_integer(uschar *, BOOL);
263 extern void    modify_variable(uschar *, void *);
264
265 extern BOOL    fd_ready(int, time_t);
266
267 extern int     filter_interpret(uschar *, int, address_item **, uschar **);
268 extern BOOL    filter_personal(string_item *, BOOL);
269 extern BOOL    filter_runtest(int, uschar *, BOOL, BOOL);
270 extern BOOL    filter_system_interpret(address_item **, uschar **);
271
272 extern uschar * fn_hdrs_added(void);
273 extern void    force_fd(int, int);
274
275 extern void    header_add(int, const char *, ...);
276 extern header_line *header_add_at_position_internal(BOOL, uschar *, BOOL, int, const char *, ...);
277 extern int     header_checkname(header_line *, BOOL);
278 extern BOOL    header_match(uschar *, BOOL, BOOL, string_item *, int, ...);
279 extern int     host_address_extract_port(uschar *);
280 extern uschar *host_and_ident(BOOL);
281 extern int     host_aton(const uschar *, int *);
282 extern void    host_build_hostlist(host_item **, const uschar *, BOOL);
283 extern ip_address_item *host_build_ifacelist(const uschar *, uschar *);
284 extern void    host_build_log_info(void);
285 extern void    host_build_sender_fullhost(void);
286 extern int     host_find_byname(host_item *, const uschar *, int,
287                                 const uschar **, BOOL);
288 extern int     host_find_bydns(host_item *, const uschar *, int, uschar *, uschar *,
289                  uschar *, const dnssec_domains *, const uschar **, BOOL *);
290 extern ip_address_item *host_find_interfaces(void);
291 extern BOOL    host_is_in_net(const uschar *, const uschar *, int);
292 extern BOOL    host_is_tls_on_connect_port(int);
293 extern int     host_item_get_port(host_item *);
294 extern void    host_mask(int, int *, int);
295 extern int     host_name_lookup(void);
296 extern int     host_nmtoa(int, int *, int, uschar *, int);
297 extern uschar *host_ntoa(int, const void *, uschar *, int *);
298 extern int     host_scan_for_local_hosts(host_item *, host_item **, BOOL *);
299
300 extern uschar *imap_utf7_encode(uschar *, const uschar *,
301                                  uschar, uschar *, uschar **);
302
303 extern void    invert_address(uschar *, uschar *);
304 extern int     ip_addr(void *, int, const uschar *, int);
305 extern int     ip_bind(int, int, uschar *, int);
306 extern int     ip_connect(int, int, const uschar *, int, int, const blob *);
307 extern int     ip_connectedsocket(int, const uschar *, int, int,
308                  int, host_item *, uschar **, const blob *);
309 extern int     ip_get_address_family(int);
310 extern void    ip_keepalive(int, const uschar *, BOOL);
311 extern int     ip_recv(client_conn_ctx *, uschar *, int, time_t);
312 extern int     ip_socket(int, int);
313
314 extern int     ip_tcpsocket(const uschar *, uschar **, int, host_item *);
315 extern int     ip_unixsocket(const uschar *, uschar **);
316 extern int     ip_streamsocket(const uschar *, uschar **, int, host_item *);
317
318 extern int     ipv6_nmtoa(int *, uschar *);
319
320 extern uschar *local_part_quote(uschar *);
321 extern int     log_open_as_exim(uschar * const);
322 extern void    log_close_all(void);
323
324 extern macro_item * macro_create(const uschar *, const uschar *, BOOL);
325 extern BOOL    macro_read_assignment(uschar *);
326 extern uschar *macros_expand(int, int *, BOOL *);
327 extern void    mainlog_close(void);
328 #ifdef WITH_CONTENT_SCAN
329 extern int     malware(const uschar *, int);
330 extern int     malware_in_file(uschar *);
331 extern void    malware_init(void);
332 extern gstring * malware_show_supported(gstring *);
333 #endif
334 extern int     match_address_list(const uschar *, BOOL, BOOL, const uschar **,
335                  unsigned int *, int, int, const uschar **);
336 extern int     match_address_list_basic(const uschar *, const uschar **, int);
337 extern int     match_check_list(const uschar **, int, tree_node **, unsigned int **,
338                  int(*)(void *, const uschar *, const uschar **, uschar **), void *, int,
339                  const uschar *, const uschar **);
340 extern int     match_isinlist(const uschar *, const uschar **, int, tree_node **,
341                  unsigned int *, int, BOOL, const uschar **);
342 extern int     match_check_string(const uschar *, const uschar *, int, BOOL, BOOL, BOOL,
343                  const uschar **);
344
345 extern void    message_start(void);
346 extern void    message_tidyup(void);
347 extern void    md5_end(md5 *, const uschar *, int, uschar *);
348 extern void    md5_mid(md5 *, const uschar *);
349 extern void    md5_start(md5 *);
350 extern void    millisleep(int);
351 #ifdef WITH_CONTENT_SCAN
352 struct mime_boundary_context;
353 extern int     mime_acl_check(uschar *acl, FILE *f,
354                  struct mime_boundary_context *, uschar **, uschar **);
355 extern int     mime_decode(const uschar **);
356 extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *);
357 extern int     mime_regex(const uschar **);
358 extern void    mime_set_anomaly(int);
359 #endif
360 extern uschar *moan_check_errorcopy(uschar *);
361 extern BOOL    moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
362                  BOOL, uschar *);
363 extern void    moan_smtp_batch(uschar *, const char *, ...) PRINTF_FUNCTION(2,3);
364 extern BOOL    moan_send_message(uschar *, int, error_block *eblock,
365                  header_line *, FILE *, uschar *);
366 extern void    moan_tell_someone(uschar *, address_item *,
367                  const uschar *, const char *, ...) PRINTF_FUNCTION(4,5);
368 extern BOOL    moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
369 extern void    moan_write_from(FILE *);
370 extern void    moan_write_references(FILE *, uschar *);
371 extern FILE   *modefopen(const uschar *, const char *, mode_t);
372
373 extern int     open_cutthrough_connection( address_item * addr );
374
375 extern uschar *parse_extract_address(const uschar *, uschar **, int *, int *, int *,
376                  BOOL);
377 extern int     parse_forward_list(const uschar *, int, address_item **, uschar **,
378                  const uschar *, uschar *, error_block **);
379 extern uschar *parse_find_address_end(const uschar *, BOOL);
380 extern const uschar *parse_find_at(const uschar *);
381 extern const uschar *parse_fix_phrase(const uschar *, int);
382 extern const uschar *parse_message_id(const uschar *, uschar **, uschar **);
383 extern const uschar *parse_quote_2047(const uschar *, int, const uschar *,
384                                       BOOL);
385 extern const uschar *parse_date_time(const uschar *str, time_t *t);
386 extern void priv_drop_temp(const uid_t, const gid_t);
387 extern void priv_restore(void);
388 extern int     vaguely_random_number(int);
389 #ifndef DISABLE_TLS
390 extern int     vaguely_random_number_fallback(int);
391 #endif
392
393 extern BOOL    queue_action(uschar *, int, uschar **, int, int);
394 extern void    queue_check_only(void);
395 extern unsigned queue_count(void);
396 extern unsigned queue_count_cached(void);
397 extern void    queue_list(int, uschar **, int);
398 #ifndef DISABLE_QUEUE_RAMP
399 extern void    queue_notify_daemon(const uschar * hostname);
400 #endif
401 extern void    queue_run(uschar *, uschar *, BOOL);
402
403 extern int     random_number(int);
404 extern const uschar *rc_to_string(int);
405 extern int     rda_interpret(redirect_block *, int, uschar *, uschar *,
406                  uschar *, uschar *, uschar *, ugid_block *, address_item **,
407                  uschar **, error_block **, int *, uschar *);
408 extern int     rda_is_filter(const uschar *);
409 extern BOOL    readconf_depends(driver_instance *, uschar *);
410 extern void    readconf_driver_init(uschar *, driver_instance **,
411                  driver_info *, int, void *, int, optionlist *, int);
412 extern uschar *readconf_find_option(void *);
413 extern void    readconf_main(BOOL);
414 extern void    readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *);
415 extern BOOL    readconf_print(const uschar *, uschar *, BOOL);
416 extern uschar *readconf_printtime(int);
417 extern uschar *readconf_readname(uschar *, int, uschar *);
418 extern int     readconf_readtime(const uschar *, int, BOOL);
419 extern void    readconf_rest(void);
420 extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *);
421 extern void    readconf_save_config(const uschar *);
422 extern void    read_message_body(BOOL);
423 extern void    receive_bomb_out(uschar *, uschar *) NORETURN;
424 extern BOOL    receive_check_fs(int);
425 extern BOOL    receive_check_set_sender(uschar *);
426 extern BOOL    receive_msg(BOOL);
427 extern int_eximarith_t receive_statvfs(BOOL, int *);
428 extern void    receive_swallow_smtp(void);
429 #ifdef WITH_CONTENT_SCAN
430 extern int     regex(const uschar **);
431 #endif
432 extern BOOL    regex_match(const pcre2_code *, const uschar *, int, uschar **);
433 extern BOOL    regex_match_and_setup(const pcre2_code *, const uschar *, int, int);
434 extern const pcre2_code *regex_must_compile(const uschar *, BOOL, BOOL);
435 extern void    retry_add_item(address_item *, uschar *, int);
436 extern BOOL    retry_check_address(const uschar *, host_item *, uschar *, BOOL,
437                  uschar **, uschar **);
438 extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
439 extern BOOL    retry_ultimate_address_timeout(uschar *, const uschar *,
440                  dbdata_retry *, time_t);
441 extern void    retry_update(address_item **, address_item **, address_item **);
442 extern const uschar *rewrite_address(const uschar *, BOOL, BOOL, rewrite_rule *, int);
443 extern const uschar *rewrite_address_qualify(const uschar *, BOOL);
444 extern header_line *rewrite_header(header_line *,
445                const uschar *, const uschar *,
446                rewrite_rule *, int, BOOL);
447 extern const uschar *rewrite_one(const uschar *, int, BOOL *, BOOL, uschar *,
448                  rewrite_rule *);
449 extern void    rewrite_test(const uschar *);
450 extern uschar *rfc2047_decode2(uschar *, BOOL, const uschar *, int, int *,
451                                      int *, uschar **);
452 extern int     route_address(address_item *, address_item **, address_item **,
453                  address_item **, address_item **, int);
454 extern int     route_check_prefix(const uschar *, const uschar *, unsigned *);
455 extern int     route_check_suffix(const uschar *, const uschar *, unsigned *);
456 extern BOOL    route_findgroup(uschar *, gid_t *);
457 extern BOOL    route_finduser(const uschar *, struct passwd **, uid_t *);
458 extern BOOL    route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
459                  uschar **);
460 extern BOOL    route_find_expanded_user(uschar *, uschar *, uschar *,
461                  struct passwd **, uid_t *, uschar **);
462 extern void    route_init(void);
463 extern gstring * route_show_supported(gstring *);
464 extern void    route_tidyup(void);
465
466 extern uschar *search_args(int, uschar *, uschar *, uschar **, const uschar *);
467 extern uschar *search_find(void *, const uschar *, uschar *, int,
468                  const uschar *, int, int, int *, const uschar *);
469 extern int     search_findtype(const uschar *, int);
470 extern int     search_findtype_partial(const uschar *, int *, const uschar **, int *,
471                  int *, const uschar **);
472 extern void   *search_open(const uschar *, int, int, uid_t *, gid_t *);
473 extern void    search_tidyup(void);
474 extern void    set_process_info(const char *, ...) PRINTF_FUNCTION(1,2);
475 extern void    sha1_end(hctx *, const uschar *, int, uschar *);
476 extern void    sha1_mid(hctx *, const uschar *);
477 extern void    sha1_start(hctx *);
478 extern int     sieve_interpret(uschar *, int, uschar *, uschar *, uschar *,
479                  uschar *, address_item **, uschar **);
480 extern void    sigalrm_handler(int);
481 extern BOOL    smtp_buffered(void);
482 extern void    smtp_closedown(uschar *);
483 extern void    smtp_command_timeout_exit(void) NORETURN;
484 extern void    smtp_command_sigterm_exit(void) NORETURN;
485 extern void    smtp_data_timeout_exit(void) NORETURN;
486 extern void    smtp_data_sigint_exit(void) NORETURN;
487 extern void    smtp_deliver_init(void);
488 extern uschar *smtp_cmd_hist(void);
489 extern int     smtp_connect(smtp_connect_args *, const blob *);
490 extern int     smtp_sock_connect(host_item *, int, int, uschar *,
491                  transport_instance * tb, int, const blob *);
492 extern int     smtp_feof(void);
493 extern int     smtp_ferror(void);
494 extern uschar *smtp_get_connection_info(void);
495 extern BOOL    smtp_get_interface(uschar *, int, address_item *,
496                  uschar **, uschar *);
497 extern BOOL    smtp_get_port(uschar *, address_item *, int *, uschar *);
498 extern int     smtp_getc(unsigned);
499 extern uschar *smtp_getbuf(unsigned *);
500 extern void    smtp_get_cache(unsigned);
501 extern BOOL    smtp_hasc(void);
502 extern int     smtp_handle_acl_fail(int, int, uschar *, uschar *);
503 extern void    smtp_log_no_mail(void);
504 extern void    smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL);
505 extern void    smtp_proxy_tls(void *, uschar *, size_t, int *, int) NORETURN;
506 extern BOOL    smtp_read_response(void *, uschar *, int, int, int);
507 extern void   *smtp_reset(void *);
508 extern void    smtp_respond(uschar *, int, BOOL, uschar *);
509 extern void    smtp_notquit_exit(uschar *, uschar *, uschar *, ...);
510 extern void    smtp_port_for_connect(host_item *, int);
511 extern void    smtp_send_prohibition_message(int, uschar *);
512 extern int     smtp_setup_msg(void);
513 extern BOOL    smtp_start_session(void);
514 extern int     smtp_ungetc(int);
515 extern BOOL    smtp_verify_helo(void);
516 extern int     smtp_write_command(void *, int, const char *, ...) PRINTF_FUNCTION(3,4);
517 #ifdef WITH_CONTENT_SCAN
518 extern int     spam(const uschar **);
519 extern FILE   *spool_mbox(unsigned long *, const uschar *, uschar **);
520 #endif
521 extern void    spool_clear_header_globals(void);
522 extern BOOL    spool_move_message(uschar *, uschar *, uschar *, uschar *);
523 extern int     spool_open_datafile(uschar *);
524 extern int     spool_open_temp(uschar *);
525 extern int     spool_read_header(uschar *, BOOL, BOOL);
526 extern uschar *spool_sender_from_msgid(const uschar *);
527 extern int     spool_write_header(uschar *, int, uschar **);
528 extern int     stdin_getc(unsigned);
529 extern int     stdin_feof(void);
530 extern int     stdin_ferror(void);
531 extern BOOL    stdin_hasc(void);
532 extern int     stdin_ungetc(int);
533
534 extern void    store_exit(void);
535 extern void    store_init(void);
536 extern void    store_writeprotect(int);
537
538 extern gstring *string_append(gstring *, int, ...) WARN_UNUSED_RESULT;
539 extern gstring *string_append_listele(gstring *, uschar, const uschar *) WARN_UNUSED_RESULT;
540 extern gstring *string_append_listele_n(gstring *, uschar, const uschar *, unsigned) WARN_UNUSED_RESULT;
541 extern gstring *string_append2_listele_n(gstring *, const uschar *, const uschar *, unsigned) WARN_UNUSED_RESULT;
542 extern uschar *string_base62(unsigned long int);
543 extern gstring *string_cat (gstring *, const uschar *     ) WARN_UNUSED_RESULT;
544 extern gstring *string_catn(gstring *, const uschar *, int) WARN_UNUSED_RESULT;
545 extern int     string_compare_by_pointer(const void *, const void *);
546 extern uschar *string_copy_dnsdomain(uschar *);
547 extern uschar *string_copy_malloc(const uschar *);
548 extern uschar *string_dequote(const uschar **);
549 extern uschar *string_format_size(int, uschar *);
550 extern int     string_interpret_escape(const uschar **);
551 extern int     string_is_ip_address(const uschar *, int *);
552 #ifdef SUPPORT_I18N
553 extern BOOL    string_is_utf8(const uschar *);
554 #endif
555 extern const uschar *string_printing2(const uschar *, int);
556 extern uschar *string_split_message(uschar *);
557 extern uschar *string_unprinting(uschar *);
558 #ifdef SUPPORT_I18N
559 extern uschar *string_address_utf8_to_alabel(const uschar *, uschar **);
560 extern uschar *string_domain_alabel_to_utf8(const uschar *, uschar **);
561 extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **);
562 extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **);
563 extern uschar *string_localpart_utf8_to_alabel(const uschar *, uschar **);
564 #endif
565
566 #define string_format(buf, siz, fmt, ...) \
567         string_format_trc(buf, siz, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
568 extern BOOL    string_format_trc(uschar *, int, const uschar *, unsigned,
569                         const char *, ...) ALMOST_PRINTF(5,6);
570
571 #define string_vformat(g, flgs, fmt, ap) \
572         string_vformat_trc(g, US __FUNCTION__, __LINE__, \
573                          STRING_SPRINTF_BUFFER_SIZE, flgs, fmt, ap)
574 extern gstring *string_vformat_trc(gstring *, const uschar *, unsigned,
575                         unsigned, unsigned, const char *, va_list);
576
577 #define string_open_failed(fmt, ...) \
578         string_open_failed_trc(US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
579 extern uschar *string_open_failed_trc(const uschar *, unsigned,
580                         const char *, ...) PRINTF_FUNCTION(3,4);
581
582 #define string_nextinlist(lp, sp, b, l) \
583         string_nextinlist_trc((lp), (sp), (b), (l), US __FUNCTION__, __LINE__)
584 extern uschar *string_nextinlist_trc(const uschar **listptr, int *separator, uschar *buffer, int buflen,
585                         const uschar * func, int line);
586
587 extern int     strcmpic(const uschar *, const uschar *);
588 extern int     strncmpic(const uschar *, const uschar *, int);
589 extern uschar *strstric(uschar *, uschar *, BOOL);
590
591 extern int     test_harness_fudged_queue_time(int);
592 extern void    tcp_init(void);
593 #ifdef EXIM_TFO_PROBE
594 extern void    tfo_probe(void);
595 #endif
596 extern void    tls_modify_variables(tls_support *);
597 extern uschar *tod_stamp(int);
598
599 extern BOOL    transport_check_waiting(const uschar *, const uschar *, int, uschar *,
600                  oicf, void*);
601 extern void    transport_init(void);
602 extern void    transport_do_pass_socket(const uschar *, const uschar *,
603                  const uschar *, uschar *, int);
604 extern BOOL    transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *, int
605 #ifdef EXPERIMENTAL_ESMTP_LIMITS
606                         , unsigned, unsigned, unsigned
607 #endif
608                         );
609 extern uschar *transport_rcpt_address(address_item *, BOOL);
610 extern BOOL    transport_set_up_command(const uschar ***, uschar *,
611                  BOOL, int, address_item *, uschar *, uschar **);
612 extern void    transport_update_waiting(host_item *, uschar *);
613 extern BOOL    transport_write_block(transport_ctx *, uschar *, int, BOOL);
614 extern void    transport_write_reset(int);
615 extern BOOL    transport_write_string(int, const char *, ...);
616 extern BOOL    transport_headers_send(transport_ctx *,
617                  BOOL (*)(transport_ctx *, uschar *, int));
618 extern gstring * transport_show_supported(gstring *);
619 extern BOOL    transport_write_message(transport_ctx *, int);
620 extern void    tree_add_duplicate(const uschar *, address_item *);
621 extern void    tree_add_nonrecipient(const uschar *);
622 extern void    tree_add_unusable(const host_item *);
623 extern void    tree_dup(tree_node **, tree_node *);
624 extern int     tree_insertnode(tree_node **, tree_node *);
625 extern tree_node *tree_search(tree_node *, const uschar *);
626 extern void    tree_write(tree_node *, FILE *);
627 extern void    tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *);
628
629 #ifdef WITH_CONTENT_SCAN
630 extern void    unspool_mbox(void);
631 #endif
632 #ifdef SUPPORT_I18N
633 extern void    utf8_version_report(FILE *);
634 #endif
635
636 extern int     verify_address(address_item *, FILE *, int, int, int, int,
637                  uschar *, uschar *, BOOL *);
638 extern int     verify_check_dnsbl(int, const uschar **, uschar **);
639 extern int     verify_check_header_address(uschar **, uschar **, int, int, int,
640                  uschar *, uschar *, int, int *);
641 extern int     verify_check_headers(uschar **);
642 extern int     verify_check_header_names_ascii(uschar **);
643 extern int     verify_check_host(uschar **);
644 extern int     verify_check_notblind(BOOL);
645 extern int     verify_check_given_host(const uschar **, const host_item *);
646 extern int     verify_check_this_host(const uschar **, unsigned int *,
647                  const uschar*, const uschar *, const uschar **);
648 extern address_item *verify_checked_sender(uschar *);
649 extern void    verify_get_ident(int);
650 extern void    verify_quota(uschar *);
651 extern int     verify_quota_call(const uschar *, int, int, uschar **);
652 extern BOOL    verify_sender(int *, uschar **);
653 extern BOOL    verify_sender_preliminary(int *, uschar **);
654 extern void    version_init(void);
655
656 extern BOOL    write_chunk(transport_ctx *, uschar *, int);
657 extern ssize_t write_to_fd_buf(int, const uschar *, size_t);
658
659
660 /******************************************************************************/
661 /* Predicate: if an address is in a tainted pool.
662 By extension, a variable pointing to this address is tainted.
663 */
664
665 static inline BOOL
666 is_tainted(const void * p)
667 {
668 #if defined(COMPILE_UTILITY) || defined(MACRO_PREDEF) || defined(EM_VERSION_C)
669 return FALSE;
670
671 #else
672 extern BOOL is_tainted_fn(const void *);
673 return is_tainted_fn(p);
674 #endif
675 }
676
677 /******************************************************************************/
678 /* String functions */
679 static inline uschar * __Ustrcat(uschar * dst, const uschar * src, const char * func, int line)
680 {
681 #if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
682 if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcat", CUS func, line);
683 #endif
684 return US strcat(CS dst, CCS src);
685 }
686 static inline uschar * __Ustrcpy(uschar * dst, const uschar * src, const char * func, int line)
687 {
688 #if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
689 if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcpy", CUS func, line);
690 #endif
691 return US strcpy(CS dst, CCS src);
692 }
693 static inline uschar * __Ustrncat(uschar * dst, const uschar * src, size_t n, const char * func, int line)
694 {
695 #if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
696 if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncat", CUS func, line);
697 #endif
698 return US strncat(CS dst, CCS src, n);
699 }
700 static inline uschar * __Ustrncpy(uschar * dst, const uschar * src, size_t n, const char * func, int line)
701 {
702 #if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
703 if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncpy", CUS func, line);
704 #endif
705 return US strncpy(CS dst, CCS src, n);
706 }
707 /*XXX will likely need unchecked copy also */
708
709
710 /* Advance the string pointer given over any whitespace.
711 Return the next char as there's enought places using it to be useful. */
712
713 #define Uskip_whitespace(sp) skip_whitespace(CUSS sp)
714
715 static inline uschar skip_whitespace(const uschar ** sp)
716 { while (isspace(**sp)) (*sp)++; return **sp; }
717
718
719 /******************************************************************************/
720
721 #if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
722 /* exim_chown - in some NFSv4 setups *seemes* to be an issue with
723 chown(<exim-uid>, <exim-gid>).
724
725 Probably because the idmapping is broken, misconfigured or set up in
726 an unusal way. (see Bug 2931). As I'm not sure, if this was a single
727 case of misconfiguration, or if there are more such broken systems
728 out, I try to impose as least impact as possible and for now just write
729 a panic log entry pointing to the bug report. You're encouraged to
730 contact the developers, if you experience this issue.
731
732 fd     the file descriptor (or -1 if not valid)
733 name   the file name for error messages or for file operations,
734   if fd is < 0
735 owner  the owner
736 group  the group
737
738 returns 0 on success, -1 on failure */
739
740 static inline int
741 exim_fchown(int fd, uid_t owner, gid_t group, const uschar *name)
742 {
743 return fchown(fd, owner, group)
744   ? exim_chown_failure(fd, name, owner, group) : 0;
745 }
746
747 static inline int
748 exim_chown(const uschar *name, uid_t owner, gid_t group)
749 {
750 return chown(CCS name, owner, group)
751   ? exim_chown_failure(-1, name, owner, group) : 0;
752 }
753 #endif  /* !MACRO_PREDEF && !COMPILE_UTILITY */
754
755 /******************************************************************************/
756 /* String functions */
757
758 #if !defined(MACRO_PREDEF)
759 /*************************************************
760 *            Copy and save string                *
761 *************************************************/
762
763 /* This function assumes that memcpy() is faster than strcpy().
764 The result is explicitly nul-terminated.
765 */
766
767 static inline uschar *
768 string_copyn_taint_trc(const uschar * s, unsigned len,
769         BOOL tainted, const char * func, int line)
770 {
771 uschar * ss = store_get_3(len + 1, tainted, func, line);
772 memcpy(ss, s, len);
773 ss[len] = '\0';
774 return ss;
775 }
776
777 static inline uschar *
778 string_copy_taint_trc(const uschar * s, BOOL tainted, const char * func, int line)
779 { return string_copyn_taint_trc(s, Ustrlen(s), tainted, func, line); }
780
781 static inline uschar *
782 string_copyn_trc(const uschar * s, unsigned len, const char * func, int line)
783 { return string_copyn_taint_trc(s, len, is_tainted(s), func, line); }
784 static inline uschar *
785 string_copy_trc(const uschar * s, const char * func, int line)
786 { return string_copy_taint_trc(s, is_tainted(s), func, line); }
787
788
789 /* String-copy functions explicitly setting the taint status */
790
791 #define string_copyn_taint(s, len, tainted) \
792         string_copyn_taint_trc((s), (len), (tainted), __FUNCTION__, __LINE__)
793 #define string_copy_taint(s, tainted) \
794         string_copy_taint_trc((s), (tainted), __FUNCTION__, __LINE__)
795
796 /* Simple string-copy functions maintaining the taint */
797
798 #define string_copyn(s, len) \
799         string_copyn_trc((s), (len), __FUNCTION__, __LINE__)
800 #define string_copy(s) \
801         string_copy_trc((s), __FUNCTION__, __LINE__)
802
803
804 /*************************************************
805 *       Copy, lowercase and save string          *
806 *************************************************/
807
808 /*
809 Argument: string to copy
810 Returns:  copy of string in new store, with letters lowercased
811 */
812
813 static inline uschar *
814 string_copylc(const uschar *s)
815 {
816 uschar *ss = store_get(Ustrlen(s) + 1, is_tainted(s));
817 uschar *p = ss;
818 while (*s != 0) *p++ = tolower(*s++);
819 *p = 0;
820 return ss;
821 }
822
823
824
825 /*************************************************
826 * Copy, lowercase, and save string, given length *
827 *************************************************/
828
829 /* It is assumed the data contains no zeros. A zero is added
830 onto the end.
831
832 Arguments:
833   s         string to copy
834   n         number of characters
835
836 Returns:    copy of string in new store, with letters lowercased
837 */
838
839 static inline uschar *
840 string_copynlc(uschar *s, int n)
841 {
842 uschar *ss = store_get(n + 1, is_tainted(s));
843 uschar *p = ss;
844 while (n-- > 0) *p++ = tolower(*s++);
845 *p = 0;
846 return ss;
847 }
848
849
850 # ifndef COMPILE_UTILITY
851 /*************************************************
852 *     Copy and save string in longterm store     *
853 *************************************************/
854
855 /* This function assumes that memcpy() is faster than strcpy().
856
857 Argument: string to copy
858 Returns:  copy of string in new store
859 */
860
861 static inline uschar *
862 string_copy_perm(const uschar *s, BOOL force_taint)
863 {
864 int old_pool = store_pool;
865 int len = Ustrlen(s) + 1;
866 uschar *ss;
867
868 store_pool = POOL_PERM;
869 ss = store_get(len, force_taint || is_tainted(s));
870 memcpy(ss, s, len);
871 store_pool = old_pool;
872 return ss;
873 }
874 # endif
875
876
877
878 /* sprintf into a buffer, taint-unchecked */
879
880 static inline void
881 string_format_nt(uschar * buf, int siz, const char * fmt, ...)
882 {
883 gstring gs = { .size = siz, .ptr = 0, .s = buf };
884 va_list ap;
885 va_start(ap, fmt);
886 (void) string_vformat(&gs, SVFMT_TAINT_NOCHK, fmt, ap);
887 va_end(ap);
888 }
889
890
891
892 /******************************************************************************/
893 /* Growable-string functions */
894
895 /* Create a growable-string with some preassigned space */
896
897 #define string_get_tainted(size, tainted) \
898         string_get_tainted_trc((size), (tainted), __FUNCTION__, __LINE__)
899
900 static inline gstring *
901 string_get_tainted_trc(unsigned size, BOOL tainted, const char * func, unsigned line)
902 {
903 gstring * g = store_get_3(sizeof(gstring) + size, tainted, func, line);
904 g->size = size;
905 g->ptr = 0;
906 g->s = US(g + 1);
907 return g;
908 }
909
910 #define string_get(size) \
911         string_get_trc((size), __FUNCTION__, __LINE__)
912
913 static inline gstring *
914 string_get_trc(unsigned size, const char * func, unsigned line)
915 {
916 return string_get_tainted_trc(size, FALSE, func, line);
917 }
918
919 /* NUL-terminate the C string in the growable-string, and return it. */
920
921 static inline uschar *
922 string_from_gstring(gstring * g)
923 {
924 if (!g) return NULL;
925 g->s[g->ptr] = '\0';
926 return g->s;
927 }
928
929 static inline unsigned
930 gstring_length(const gstring * g)
931 {
932 return g ? (unsigned)g->ptr : 0;
933 }
934
935
936 #define gstring_release_unused(g) \
937         gstring_release_unused_trc(g, __FUNCTION__, __LINE__)
938
939 static inline void
940 gstring_release_unused_trc(gstring * g, const char * file, unsigned line)
941 {
942 if (g) store_release_above_3(g->s + (g->size = g->ptr + 1), file, line);
943 }
944
945
946 /* sprintf-append to a growable-string */
947
948 #define string_fmt_append(g, fmt, ...) \
949         string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
950         SVFMT_EXTEND|SVFMT_REBUFFER, fmt, __VA_ARGS__)
951
952 #define string_fmt_append_f(g, flgs, fmt, ...) \
953         string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
954         flgs,         fmt, __VA_ARGS__)
955
956 static inline gstring *
957 string_fmt_append_f_trc(gstring * g, const uschar * func, unsigned line,
958   unsigned flags, const char *format, ...)
959 {
960 va_list ap;
961 va_start(ap, format);
962 g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
963                         flags, format, ap);
964 va_end(ap);
965 return g;
966 }
967
968
969 /* Copy the content of a string to tainted memory */
970
971 static inline void
972 gstring_rebuffer(gstring * g)
973 {
974 uschar * s = store_get(g->size, TRUE);
975 memcpy(s, g->s, g->ptr);
976 g->s = s;
977 }
978
979
980 # ifndef COMPILE_UTILITY
981 /******************************************************************************/
982 /* Use store_malloc for DNSA structs, and explicit frees. Using the same pool
983 for them as the strings we proceed to copy from them meant they could not be
984 released, hence blowing 64k for every DNS lookup. That mounted up. With malloc
985 we do have to take care over marking tainted all copied strings.  A separate pool
986 could be used and would handle that implicitly. */
987
988 #define store_get_dns_answer() store_get_dns_answer_trc(CUS __FUNCTION__, __LINE__)
989
990 static inline dns_answer *
991 store_get_dns_answer_trc(const uschar * func, unsigned line)
992 {
993 /* return store_get_3(sizeof(dns_answer), TRUE, CCS func, line);   use tainted mem */
994 return store_malloc_3(sizeof(dns_answer), CCS func, line);
995 }
996
997 #define store_free_dns_answer(dnsa) store_free_dns_answer_trc(dnsa, CUS __FUNCTION__, __LINE__)
998
999 static inline void
1000 store_free_dns_answer_trc(dns_answer * dnsa, const uschar * func, unsigned line)
1001 {
1002 store_free_3(dnsa, CCS func, line);
1003 }
1004
1005 /******************************************************************************/
1006 /* Routines with knowledge of spool layout */
1007
1008 static inline void
1009 spool_pname_buf(uschar * buf, int len)
1010 {
1011 snprintf(CS buf, len, "%s/%s/input", spool_directory, queue_name);
1012 }
1013
1014 static inline uschar *
1015 spool_dname(const uschar * purpose, uschar * subdir)
1016 {
1017 return string_sprintf("%s/%s/%s/%s",
1018         spool_directory, queue_name, purpose, subdir);
1019 }
1020 # endif
1021
1022 static inline uschar *
1023 spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir)
1024 {
1025 return string_sprintf("%s%s%s%s%s",
1026                     q, *q ? "/" : "",
1027                     purpose,
1028                     *subdir ? "/" : "", subdir);
1029 }
1030
1031 static inline uschar *
1032 spool_sname(const uschar * purpose, uschar * subdir)
1033 {
1034 return spool_q_sname(purpose, queue_name, subdir);
1035 }
1036
1037 static inline uschar *
1038 spool_q_fname(const uschar * purpose, const uschar * q,
1039         const uschar * subdir, const uschar * fname, const uschar * suffix)
1040 {
1041 return string_sprintf("%s/%s/%s/%s/%s%s",
1042         spool_directory, q, purpose, subdir, fname, suffix);
1043 }
1044
1045 static inline uschar *
1046 spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
1047         const uschar * suffix)
1048 {
1049 #ifdef COMPILE_UTILITY          /* version avoiding string-extension */
1050 int len = Ustrlen(spool_directory) + 1 + Ustrlen(queue_name) + 1 + Ustrlen(purpose) + 1
1051         + Ustrlen(subdir) + 1 + Ustrlen(fname) + Ustrlen(suffix) + 1;
1052 uschar * buf = store_get(len, FALSE);
1053 string_format(buf, len, "%s/%s/%s/%s/%s%s",
1054         spool_directory, queue_name, purpose, subdir, fname, suffix);
1055 return buf;
1056 #else
1057 return spool_q_fname(purpose, queue_name, subdir, fname, suffix);
1058 #endif
1059 }
1060
1061 static inline void
1062 set_subdir_str(uschar * subdir_str, const uschar * name,
1063         int search_sequence)
1064 {
1065 subdir_str[0] = split_spool_directory == (search_sequence == 0)
1066        ? name[5] : '\0';
1067 subdir_str[1] = '\0';
1068 }
1069
1070 /******************************************************************************/
1071 /* Time calculations */
1072
1073 /* Diff two times (later, earlier) returning diff in 1st arg */
1074 static inline void
1075 timediff(struct timeval * later, const struct timeval * earlier)
1076 {
1077 later->tv_sec -= earlier->tv_sec;
1078 if ((later->tv_usec -= earlier->tv_usec) < 0)
1079   {
1080   later->tv_sec--;
1081   later->tv_usec += 1000*1000;
1082   }
1083 }
1084
1085 static inline void
1086 timesince(struct timeval * diff, const struct timeval * then)
1087 {
1088 gettimeofday(diff, NULL);
1089 timediff(diff, then);
1090 }
1091
1092 static inline uschar *
1093 string_timediff(const struct timeval * diff)
1094 {
1095 static uschar buf[sizeof("0.000s")];
1096
1097 if (diff->tv_sec >= 5 || !LOGGING(millisec))
1098   return readconf_printtime((int)diff->tv_sec);
1099
1100 snprintf(CS buf, sizeof(buf), "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
1101 return buf;
1102 }
1103
1104
1105 static inline uschar *
1106 string_timesince(const struct timeval * then)
1107 {
1108 struct timeval diff;
1109 timesince(&diff, then);
1110 return string_timediff(&diff);
1111 }
1112
1113 static inline void
1114 report_time_since(const struct timeval * t0, const uschar * where)
1115 {
1116 # ifdef MEASURE_TIMING
1117 struct timeval diff;
1118 timesince(&diff, t0);
1119 fprintf(stderr, "%d %s:\t%ld.%06ld\n",
1120        (uint)getpid(), where, (long)diff.tv_sec, (long)diff.tv_usec);
1121 # endif
1122 }
1123
1124
1125 static inline void
1126 testharness_pause_ms(int millisec)
1127 {
1128 #ifndef MEASURE_TIMING
1129 if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec);
1130 #endif
1131 }
1132
1133 /******************************************************************************/
1134 /* Taint-checked file opens */
1135 static inline uschar *
1136 is_tainted2(const void *p, int lflags, const char* fmt, ...)
1137 {
1138 va_list ap;
1139 uschar *msg;
1140 rmark mark;
1141
1142 if (!is_tainted(p))
1143   return NULL;
1144
1145 mark = store_mark();
1146 va_start(ap, fmt);
1147 msg = string_from_gstring(string_vformat(NULL, SVFMT_TAINT_NOCHK|SVFMT_EXTEND, fmt, ap));
1148 va_end(ap);
1149
1150 #ifdef ALLOW_INSECURE_TAINTED_DATA
1151 if (allow_insecure_tainted_data)
1152   {
1153   if LOGGING(tainted) log_write(0, LOG_MAIN, "Warning: %s", msg);
1154   store_reset(mark);
1155   return NULL;
1156   }
1157 #endif
1158
1159 if (lflags) log_write(0, lflags, "%s", msg);
1160 return msg; /* no store_reset(), as the message might be used afterwards and Exim
1161             is expected to exit anyway, so we do not care about the leaked
1162             storage */
1163 }
1164
1165 static inline int
1166 exim_open2(const char *pathname, int flags)
1167 {
1168 if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
1169   return open(pathname, flags);
1170 errno = EACCES;
1171 return -1;
1172 }
1173
1174 static inline int
1175 exim_open(const char *pathname, int flags, mode_t mode)
1176 {
1177 if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
1178   return open(pathname, flags, mode);
1179 errno = EACCES;
1180 return -1;
1181 }
1182 #ifdef EXIM_HAVE_OPENAT
1183 static inline int
1184 exim_openat(int dirfd, const char *pathname, int flags)
1185 {
1186 if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
1187   return openat(dirfd, pathname, flags);
1188 errno = EACCES;
1189 return -1;
1190 }
1191 static inline int
1192 exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
1193 {
1194 if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
1195   return openat(dirfd, pathname, flags, mode);
1196 errno = EACCES;
1197 return -1;
1198 }
1199 #endif
1200
1201 static inline FILE *
1202 exim_fopen(const char *pathname, const char *mode)
1203 {
1204 if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
1205   return fopen(pathname, mode);
1206 errno = EACCES;
1207 return NULL;
1208 }
1209
1210 static inline DIR *
1211 exim_opendir(const uschar * name)
1212 {
1213 if (!is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name))
1214   return opendir(CCS name);
1215 errno = EACCES;
1216 return NULL;
1217 }
1218
1219 /******************************************************************************/
1220 # if !defined(COMPILE_UTILITY)
1221 /* Process manipulation */
1222
1223 static inline pid_t
1224 exim_fork(const unsigned char * purpose)
1225 {
1226 pid_t pid;
1227 DEBUG(D_any) debug_printf("%s forking for %s\n", process_purpose, purpose);
1228 if ((pid = fork()) == 0)
1229   {
1230   process_purpose = purpose;
1231   DEBUG(D_any) debug_printf("postfork: %s\n", purpose);
1232   }
1233 else
1234   {
1235   testharness_pause_ms(100); /* let child work */
1236   DEBUG(D_any) debug_printf("%s forked for %s: %d\n", process_purpose, purpose, (int)pid);
1237   }
1238 return pid;
1239 }
1240
1241
1242 static inline pid_t
1243 child_open_exim(int * fdptr, const uschar * purpose)
1244 { return child_open_exim_function(fdptr, purpose); }
1245
1246 static inline pid_t
1247 child_open_exim2(int * fdptr, uschar * sender,
1248   uschar * sender_auth, const uschar * purpose)
1249 { return child_open_exim2_function(fdptr, sender, sender_auth, purpose); }
1250
1251 static inline pid_t
1252 child_open(uschar **argv, uschar **envp, int newumask, int *infdptr,
1253   int *outfdptr, BOOL make_leader, const uschar * purpose)
1254 { return child_open_function(argv, envp, newumask, infdptr,
1255   outfdptr, make_leader, purpose);
1256 }
1257
1258 # endif /* !COMPILE_UTILITY */
1259
1260 /******************************************************************************/
1261 #endif  /* !MACRO_PREDEF */
1262
1263 #endif  /* _FUNCTIONS_H_ */
1264
1265 /* vi: aw
1266 */
1267 /* End of functions.h */