string handling: strlen for gstring
[exim.git] / src / src / functions.h
CommitLineData
059ec3d9
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
f9ba5e22 5/* Copyright (c) University of Cambridge 1995 - 2018 */
059ec3d9
PH
6/* See the file NOTICE for conditions of use and distribution. */
7
8
9/* Prototypes for functions that appear in various modules. Gathered together
10to avoid having a lot of tiddly little headers with only a couple of lines in
11them. However, some functions that are used (or not used) by utility programs
12are in in fact in separate headers. */
b66fecb4
HSHR
13#ifndef _FUNCTIONS_H_
14#define _FUNCTIONS_H_
059ec3d9 15
9f01e50d
JH
16#include <sys/time.h>
17
059ec3d9
PH
18
19#ifdef EXIM_PERL
acec9514 20extern gstring *call_perl_cat(gstring *, uschar **, uschar *,
268d00ff 21 uschar **) WARN_UNUSED_RESULT;
059ec3d9
PH
22extern void cleanup_perl(void);
23extern uschar *init_perl(uschar *);
24#endif
25
26
01603eec 27#ifndef DISABLE_TLS
a799883d
PP
28extern const char *
29 std_dh_prime_default(void);
30extern const char *
31 std_dh_prime_named(const uschar *);
9d1c15ef 32
9e4dddbd 33extern uschar * tls_cert_crl_uri(void *, uschar * mod);
9d1c15ef 34extern uschar * tls_cert_ext_by_oid(void *, uschar *, int);
9e4dddbd
JH
35extern uschar * tls_cert_issuer(void *, uschar * mod);
36extern uschar * tls_cert_not_before(void *, uschar * mod);
37extern uschar * tls_cert_not_after(void *, uschar * mod);
38extern uschar * tls_cert_ocsp_uri(void *, uschar * mod);
39extern uschar * tls_cert_serial_number(void *, uschar * mod);
40extern uschar * tls_cert_signature(void *, uschar * mod);
41extern uschar * tls_cert_signature_algorithm(void *, uschar * mod);
42extern uschar * tls_cert_subject(void *, uschar * mod);
43extern uschar * tls_cert_subject_altname(void *, uschar * mod);
44extern uschar * tls_cert_version(void *, uschar * mod);
9d1c15ef 45
59b87190 46extern uschar * tls_cert_der_b64(void * cert);
6a8a60e0
JH
47extern uschar * tls_cert_fprt_md5(void *);
48extern uschar * tls_cert_fprt_sha1(void *);
9ef9101c 49extern uschar * tls_cert_fprt_sha256(void *);
6a8a60e0 50
6b5cbf74 51extern void tls_clean_env(void);
c05bdbd6
JH
52extern BOOL tls_client_start(client_conn_ctx *, smtp_connect_args *,
53 void *, tls_support *, uschar **);
54
74f1a423 55extern void tls_close(void *, int);
925ac8e4 56extern BOOL tls_could_read(void);
b10c87b3 57extern void tls_daemon_init(void);
d85cdeb5 58extern BOOL tls_dropprivs_validate_require_cipher(BOOL);
2944124c 59extern BOOL tls_export_cert(uschar *, size_t, void *);
059ec3d9
PH
60extern int tls_feof(void);
61extern int tls_ferror(void);
790fbb71 62extern void tls_free_cert(void **);
bd8fbe36 63extern int tls_getc(unsigned);
0d81dabc 64extern uschar *tls_getbuf(unsigned *);
584e96c6 65extern void tls_get_cache(void);
b2827658 66extern BOOL tls_import_cert(const uschar *, void **);
74f1a423 67extern int tls_read(void *, uschar *, size_t);
cf0c6164 68extern int tls_server_start(const uschar *, uschar **);
58eb016e 69extern BOOL tls_smtp_buffered(void);
059ec3d9 70extern int tls_ungetc(int);
74f1a423 71extern int tls_write(void *, const uschar *, size_t, BOOL);
3375e053 72extern uschar *tls_validate_require_cipher(void);
36f12725 73extern void tls_version_report(FILE *);
de517fd3 74# ifdef USE_OPENSSL
77bb000f 75extern BOOL tls_openssl_options_parse(uschar *, long *);
e51c7be2 76# endif
55414b25
JH
77extern uschar * tls_field_from_dn(uschar *, const uschar *);
78extern BOOL tls_is_name_for_cert(const uschar *, void *);
0e66b3b6 79
c0635b6d 80# ifdef SUPPORT_DANE
4b0fe319 81extern int tlsa_lookup(const host_item *, dns_answer *, BOOL);
0e66b3b6
JH
82# endif
83
01603eec 84#endif /*DISABLE_TLS*/
059ec3d9
PH
85
86
87/* Everything else... */
88
89extern acl_block *acl_read(uschar *(*)(void), uschar **);
90extern int acl_check(int, uschar *, uschar *, uschar **, uschar **);
05caaeaa 91extern int acl_eval(int, uschar *, uschar **, uschar **);
333eea9c 92
38a0a95f
PH
93extern tree_node *acl_var_create(uschar *);
94extern void acl_var_write(uschar *, uschar *, void *);
617d3932
JH
95
96#ifdef EXPERIMENTAL_ARC
97extern void *arc_ams_setup_sign_bodyhash(void);
98extern const uschar *arc_header_feed(gstring *, BOOL);
99extern gstring *arc_sign(const uschar *, gstring *, uschar **);
b3d9ebf5 100extern void arc_sign_init(void);
617d3932 101extern const uschar *acl_verify_arc(void);
9cffa436 102extern uschar * fn_arc_domains(void);
617d3932
JH
103#endif
104
cf0812d5 105extern void assert_no_variables(void *, int, const char *, int);
e1af7642 106extern int auth_call_pam(const uschar *, uschar **);
059ec3d9 107extern int auth_call_pwcheck(uschar *, uschar **);
93a6fce2
JH
108extern int auth_call_radius(const uschar *, uschar **);
109extern int auth_call_saslauthd(const uschar *, const uschar *,
110 const uschar *, const uschar *, uschar **);
16ff981e 111extern int auth_check_serv_cond(auth_instance *);
44bbabb5 112extern int auth_check_some_cond(auth_instance *, uschar *, uschar *, int);
37942ad8
JH
113extern int auth_client_item(void *, auth_instance *, const uschar **,
114 unsigned, int, uschar *, int);
44bbabb5 115
e1d04f48 116
1f20760b 117extern int auth_get_data(uschar **, const uschar *, int);
059ec3d9 118extern int auth_get_no64_data(uschar **, uschar *);
8238bc7b 119extern int auth_prompt(const uschar *);
37942ad8 120extern int auth_read_input(const uschar *);
adf73d37 121extern void auth_show_supported(FILE *);
059ec3d9
PH
122extern uschar *auth_xtextencode(uschar *, int);
123extern int auth_xtextdecode(uschar *, uschar **);
124
c9cf9ac4
JH
125#ifdef EXPERIMENTAL_ARC
126extern gstring *authres_arc(gstring *);
dfbcb5ac
JH
127#endif
128#ifndef DISABLE_DKIM
129extern gstring *authres_dkim(gstring *);
130#endif
1a2e76e1 131#ifdef SUPPORT_DMARC
c9cf9ac4
JH
132extern gstring *authres_dmarc(gstring *);
133#endif
134extern gstring *authres_smtpauth(gstring *);
135#ifdef SUPPORT_SPF
136extern gstring *authres_spf(gstring *);
617d3932 137#endif
dfbcb5ac 138
1f20760b 139extern uschar *b64encode(const uschar *, int);
b1a32a3c 140extern uschar *b64encode_taint(const uschar *, int, BOOL);
35cf75e9 141extern int b64decode(const uschar *, uschar **);
bd8fbe36 142extern int bdat_getc(unsigned);
0d81dabc 143extern uschar *bdat_getbuf(unsigned *);
f6f4a58d 144extern int bdat_ungetc(int);
1ebe15c3
JH
145extern void bdat_flush_data(void);
146
6c6d6e48
TF
147extern void bits_clear(unsigned int *, size_t, int *);
148extern void bits_set(unsigned int *, size_t, int *);
149
57cc2785 150extern void cancel_cutthrough_connection(BOOL, const uschar *);
55414b25 151extern int check_host(void *, const uschar *, const uschar **, uschar **);
059ec3d9 152extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
55414b25
JH
153extern pid_t child_open_uid(const uschar **, const uschar **, int,
154 uid_t *, gid_t *, int *, int *, uschar *, BOOL);
bc3c7bb7 155extern BOOL cleanup_environment(void);
6851a9c5
JH
156extern void cutthrough_data_puts(uschar *, int);
157extern void cutthrough_data_put_nl(void);
e4bdf652
JH
158extern uschar *cutthrough_finaldot(void);
159extern BOOL cutthrough_flush_send(void);
160extern BOOL cutthrough_headers_send(void);
161extern BOOL cutthrough_predata(void);
57cc2785 162extern void release_cutthrough_connection(const uschar *);
059ec3d9
PH
163
164extern void daemon_go(void);
6a8f9482
TK
165
166#ifdef EXPERIMENTAL_DCC
167extern int dcc_process(uschar **);
168#endif
169
ed7f7860 170extern void debug_logging_activate(uschar *, uschar *);
b0d68adc 171extern void debug_logging_stop(void);
55414b25 172extern void debug_print_argv(const uschar **);
059ec3d9 173extern void debug_print_ids(uschar *);
e1d04f48 174extern void debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2);
059ec3d9
PH
175extern void debug_print_string(uschar *);
176extern void debug_print_tree(tree_node *);
398f9af3 177extern void debug_vprintf(int, const char *, va_list);
6c6d6e48
TF
178extern void decode_bits(unsigned int *, size_t, int *,
179 uschar *, bit_table *, int, uschar *, int);
01446a56 180extern void delete_pid_file(void);
059ec3d9 181extern address_item *deliver_make_addr(uschar *, BOOL);
817d9f57 182extern void delivery_log(int, address_item *, int, uschar *);
059ec3d9 183extern int deliver_message(uschar *, BOOL, BOOL);
e0df1c83 184extern void deliver_msglog(const char *, ...) PRINTF_FUNCTION(1,2);
059ec3d9
PH
185extern void deliver_set_expansions(address_item *);
186extern int deliver_split_address(address_item *);
187extern void deliver_succeeded(address_item *);
a39bd74d
JB
188
189extern uschar *deliver_get_sender_address (uschar *id);
57cc2785 190extern void delivery_re_exec(int);
a39bd74d 191
1ba28e2b 192extern BOOL directory_make(const uschar *, const uschar *, int, BOOL);
80a47a2c 193#ifndef DISABLE_DKIM
fc2ba7b9 194extern uschar *dkim_exim_query_dns_txt(const uschar *);
617d3932
JH
195extern void dkim_exim_sign_init(void);
196
42055a33 197extern BOOL dkim_transport_write_message(transport_ctx *,
b9df1829 198 struct ob_dkim *, const uschar ** errstr);
f7572e5a 199#endif
059ec3d9 200extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
476be7e2 201extern int dns_basic_lookup(dns_answer *, const uschar *, int);
152481a0 202extern uschar *dns_build_reverse(const uschar *);
a713f766 203extern time_t dns_expire_from_soa(dns_answer *, int);
8c51eead 204extern void dns_init(BOOL, BOOL, BOOL);
0539a19d 205extern BOOL dns_is_aa(const dns_answer *);
1dc92d5a 206extern BOOL dns_is_secure(const dns_answer *);
55414b25 207extern int dns_lookup(dns_answer *, const uschar *, int, const uschar **);
476be7e2 208extern void dns_pattern_init(void);
55414b25 209extern int dns_special_lookup(dns_answer *, const uschar *, int, const uschar **);
dd708fd7 210extern dns_record *dns_next_rr(const dns_answer *, dns_scan *, int);
059ec3d9 211extern uschar *dns_text_type(int);
36a3ae5f 212extern void dscp_list_to_stream(FILE *);
9e4f5962 213extern BOOL dscp_lookup(const uschar *, int, int *, int *, int *);
059ec3d9
PH
214
215extern void enq_end(uschar *);
e8ae7214 216extern BOOL enq_start(uschar *, unsigned);
0cbf2b82 217#ifndef DISABLE_EVENT
55414b25 218extern uschar *event_raise(uschar *, const uschar *, uschar *);
5ef5dd52 219extern void msg_event_raise(const uschar *, const address_item *);
774ef2d7 220#endif
b66fecb4
HSHR
221
222extern int exim_chown_failure(int, const uschar*, uid_t, gid_t);
37f3dc43 223extern const uschar * exim_errstr(int);
1d1e7973 224extern void exim_exit(int, const uschar *) NORETURN;
059ec3d9
PH
225extern void exim_nullstd(void);
226extern void exim_setugid(uid_t, gid_t, BOOL, uschar *);
f3ebb786 227extern void exim_underbar_exit(int);
059ec3d9 228extern void exim_wait_tick(struct timeval *, int);
9c695f6d
JH
229extern int exp_bool(address_item *addr,
230 uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue,
231 uschar *svalue, BOOL *rvalue);
059ec3d9 232extern BOOL expand_check_condition(uschar *, uschar *, uschar *);
617d3932 233extern uschar *expand_file_big_buffer(const uschar *);
93a6fce2
JH
234extern uschar *expand_string(uschar *); /* public, cannot make const */
235extern const uschar *expand_cstring(const uschar *); /* ... so use this one */
f42deca9 236extern uschar *expand_hide_passwords(uschar * );
55414b25 237extern uschar *expand_string_copy(const uschar *);
97d17305 238extern int_eximarith_t expand_string_integer(uschar *, BOOL);
d9b2312b 239extern void modify_variable(uschar *, void *);
059ec3d9 240
0a5441fc 241extern BOOL fd_ready(int, time_t);
4e71661f 242
059ec3d9
PH
243extern int filter_interpret(uschar *, int, address_item **, uschar **);
244extern BOOL filter_personal(string_item *, BOOL);
f05da2e8 245extern BOOL filter_runtest(int, uschar *, BOOL, BOOL);
059ec3d9
PH
246extern BOOL filter_system_interpret(address_item **, uschar **);
247
362145b5
JH
248extern uschar * fn_hdrs_added(void);
249
1ba28e2b 250extern void header_add(int, const char *, ...);
049782c0 251extern header_line *header_add_at_position_internal(BOOL, uschar *, BOOL, int, const char *, ...);
059ec3d9
PH
252extern int header_checkname(header_line *, BOOL);
253extern BOOL header_match(uschar *, BOOL, BOOL, string_item *, int, ...);
7cd1141b 254extern int host_address_extract_port(uschar *);
059ec3d9 255extern uschar *host_and_ident(BOOL);
55414b25
JH
256extern int host_aton(const uschar *, int *);
257extern void host_build_hostlist(host_item **, const uschar *, BOOL);
258extern ip_address_item *host_build_ifacelist(const uschar *, uschar *);
059ec3d9
PH
259extern void host_build_log_info(void);
260extern void host_build_sender_fullhost(void);
a207d5dd 261extern int host_find_byname(host_item *, const uschar *, int,
1f155f8e 262 const uschar **, BOOL);
55414b25 263extern int host_find_bydns(host_item *, const uschar *, int, uschar *, uschar *,
7cd171b7 264 uschar *, const dnssec_domains *, const uschar **, BOOL *);
059ec3d9 265extern ip_address_item *host_find_interfaces(void);
55414b25 266extern BOOL host_is_in_net(const uschar *, const uschar *, int);
059ec3d9 267extern BOOL host_is_tls_on_connect_port(int);
7cd1141b 268extern int host_item_get_port(host_item *);
059ec3d9
PH
269extern void host_mask(int, int *, int);
270extern int host_name_lookup(void);
6f0c9a4f 271extern int host_nmtoa(int, int *, int, uschar *, int);
059ec3d9
PH
272extern uschar *host_ntoa(int, const void *, uschar *, int *);
273extern int host_scan_for_local_hosts(host_item *, host_item **, BOOL *);
274
94431adb 275extern uschar *imap_utf7_encode(uschar *, const uschar *,
ed0512a1
JH
276 uschar, uschar *, uschar **);
277
83e029d5 278extern void invert_address(uschar *, uschar *);
7eb6c37c 279extern int ip_addr(void *, int, const uschar *, int);
059ec3d9 280extern int ip_bind(int, int, uschar *, int);
0ab63f3d 281extern int ip_connect(int, int, const uschar *, int, int, const blob *);
b1f8e4f8 282extern int ip_connectedsocket(int, const uschar *, int, int,
4a5cbaff 283 int, host_item *, uschar **, const blob *);
13363eba 284extern int ip_get_address_family(int);
55414b25 285extern void ip_keepalive(int, const uschar *, BOOL);
0a5441fc 286extern int ip_recv(client_conn_ctx *, uschar *, int, time_t);
059ec3d9
PH
287extern int ip_socket(int, int);
288
3e60dd41
JH
289extern int ip_tcpsocket(const uschar *, uschar **, int);
290extern int ip_unixsocket(const uschar *, uschar **);
291extern int ip_streamsocket(const uschar *, uschar **, int);
292
fc4a7f70
JH
293extern int ipv6_nmtoa(int *, uschar *);
294
921b12ca 295extern uschar *local_part_quote(uschar *);
4840604e 296extern int log_create(uschar *);
921b12ca 297extern int log_create_as_exim(uschar *);
059ec3d9
PH
298extern void log_close_all(void);
299
d185889f 300extern macro_item * macro_create(const uschar *, const uschar *, BOOL);
c246a1de
JH
301extern BOOL macro_read_assignment(uschar *);
302extern uschar *macros_expand(int, int *, BOOL *);
9cd319d9 303extern void mainlog_close(void);
8523533c 304#ifdef WITH_CONTENT_SCAN
0f0c8159 305extern int malware(const uschar *, int);
dbc4b90d 306extern int malware_in_file(uschar *);
476be7e2 307extern void malware_init(void);
c11d665d 308extern void malware_show_supported(FILE *);
8523533c 309#endif
55414b25
JH
310extern int match_address_list(const uschar *, BOOL, BOOL, const uschar **,
311 unsigned int *, int, int, const uschar **);
36d295f1 312extern int match_address_list_basic(const uschar *, const uschar **, int);
55414b25
JH
313extern int match_check_list(const uschar **, int, tree_node **, unsigned int **,
314 int(*)(void *, const uschar *, const uschar **, uschar **), void *, int,
315 const uschar *, const uschar **);
316extern int match_isinlist(const uschar *, const uschar **, int, tree_node **,
317 unsigned int *, int, BOOL, const uschar **);
318extern int match_check_string(const uschar *, const uschar *, int, BOOL, BOOL, BOOL,
319 const uschar **);
059ec3d9
PH
320extern void md5_end(md5 *, const uschar *, int, uschar *);
321extern void md5_mid(md5 *, const uschar *);
322extern void md5_start(md5 *);
323extern void millisleep(int);
8523533c
TK
324#ifdef WITH_CONTENT_SCAN
325struct mime_boundary_context;
54cdb463
PH
326extern int mime_acl_check(uschar *acl, FILE *f,
327 struct mime_boundary_context *, uschar **, uschar **);
55414b25 328extern int mime_decode(const uschar **);
f4d091fb 329extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *);
55414b25 330extern int mime_regex(const uschar **);
f4d091fb 331extern void mime_set_anomaly(int);
8523533c 332#endif
059ec3d9
PH
333extern uschar *moan_check_errorcopy(uschar *);
334extern BOOL moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
335 BOOL, uschar *);
e0df1c83 336extern void moan_smtp_batch(uschar *, const char *, ...) PRINTF_FUNCTION(2,3);
5455f548
JH
337extern BOOL moan_send_message(uschar *, int, error_block *eblock,
338 header_line *, FILE *, uschar *);
1ba28e2b 339extern void moan_tell_someone(uschar *, address_item *,
e0df1c83 340 const uschar *, const char *, ...) PRINTF_FUNCTION(4,5);
059ec3d9 341extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
0e22dfd1 342extern void moan_write_from(FILE *);
d6c829b9 343extern void moan_write_references(FILE *, uschar *);
1ba28e2b 344extern FILE *modefopen(const uschar *, const char *, mode_t);
059ec3d9 345
f9334a28 346extern int open_cutthrough_connection( address_item * addr );
e4bdf652 347
059ec3d9
PH
348extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
349 BOOL);
350extern int parse_forward_list(uschar *, int, address_item **, uschar **,
55414b25 351 const uschar *, uschar *, error_block **);
059ec3d9
PH
352extern uschar *parse_find_address_end(uschar *, BOOL);
353extern uschar *parse_find_at(uschar *);
55414b25 354extern const uschar *parse_fix_phrase(const uschar *, int, uschar *, int);
30dba1e6 355extern uschar *parse_message_id(uschar *, uschar **, uschar **);
55414b25 356extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL);
43ad7b7d 357extern uschar *parse_date_time(uschar *str, time_t *t);
17c76198 358extern int vaguely_random_number(int);
01603eec 359#ifndef DISABLE_TLS
17c76198
PP
360extern int vaguely_random_number_fallback(int);
361#endif
059ec3d9
PH
362
363extern BOOL queue_action(uschar *, int, uschar **, int, int);
364extern void queue_check_only(void);
365extern void queue_list(int, uschar **, int);
366extern void queue_count(void);
367extern void queue_run(uschar *, uschar *, BOOL);
368
369extern int random_number(int);
aeb65e91 370extern const uschar *rc_to_string(int);
e4a89c47 371extern int rda_interpret(redirect_block *, int, uschar *, uschar *,
efd9a422
MH
372 uschar *, uschar *, uschar *, ugid_block *, address_item **,
373 uschar **, error_block **, int *, uschar *);
059ec3d9
PH
374extern int rda_is_filter(const uschar *);
375extern BOOL readconf_depends(driver_instance *, uschar *);
376extern void readconf_driver_init(uschar *, driver_instance **,
377 driver_info *, int, void *, int, optionlist *, int);
378extern uschar *readconf_find_option(void *);
34e86e20 379extern void readconf_main(BOOL);
383832ef 380extern void readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *);
2be324ee 381extern BOOL readconf_print(uschar *, uschar *, BOOL);
059ec3d9
PH
382extern uschar *readconf_printtime(int);
383extern uschar *readconf_readname(uschar *, int, uschar *);
1ad6489e 384extern int readconf_readtime(const uschar *, int, BOOL);
bf3c2c6b 385extern void readconf_rest(void);
55414b25 386extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *);
bf3c2c6b 387extern void readconf_save_config(const uschar *);
328895cc 388extern void read_message_body(BOOL);
1d1e7973 389extern void receive_bomb_out(uschar *, uschar *) NORETURN;
059ec3d9
PH
390extern BOOL receive_check_fs(int);
391extern BOOL receive_check_set_sender(uschar *);
392extern BOOL receive_msg(BOOL);
a45431fa 393extern int_eximarith_t receive_statvfs(BOOL, int *);
059ec3d9 394extern void receive_swallow_smtp(void);
8523533c 395#ifdef WITH_CONTENT_SCAN
55414b25 396extern int regex(const uschar **);
8523533c 397#endif
1dc92d5a 398extern BOOL regex_match_and_setup(const pcre *, const uschar *, int, int);
476be7e2 399extern const pcre *regex_must_compile(const uschar *, BOOL, BOOL);
059ec3d9 400extern void retry_add_item(address_item *, uschar *, int);
55414b25 401extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL,
059ec3d9 402 uschar **, uschar **);
55414b25
JH
403extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
404extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *,
ba9af0af 405 dbdata_retry *, time_t);
059ec3d9
PH
406extern void retry_update(address_item **, address_item **, address_item **);
407extern uschar *rewrite_address(uschar *, BOOL, BOOL, rewrite_rule *, int);
408extern uschar *rewrite_address_qualify(uschar *, BOOL);
55414b25
JH
409extern header_line *rewrite_header(header_line *,
410 const uschar *, const uschar *,
059ec3d9
PH
411 rewrite_rule *, int, BOOL);
412extern uschar *rewrite_one(uschar *, int, BOOL *, BOOL, uschar *,
413 rewrite_rule *);
414extern void rewrite_test(uschar *);
415extern uschar *rfc2047_decode2(uschar *, BOOL, uschar *, int, int *, int *,
416 uschar **);
417extern int route_address(address_item *, address_item **, address_item **,
418 address_item **, address_item **, int);
55414b25
JH
419extern int route_check_prefix(const uschar *, const uschar *);
420extern int route_check_suffix(const uschar *, const uschar *);
059ec3d9 421extern BOOL route_findgroup(uschar *, gid_t *);
55414b25 422extern BOOL route_finduser(const uschar *, struct passwd **, uid_t *);
059ec3d9
PH
423extern BOOL route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
424 uschar **);
425extern BOOL route_find_expanded_user(uschar *, uschar *, uschar *,
426 struct passwd **, uid_t *, uschar **);
427extern void route_init(void);
adf73d37 428extern void route_show_supported(FILE *);
059ec3d9
PH
429extern void route_tidyup(void);
430
55414b25 431extern uschar *search_find(void *, uschar *, uschar *, int, const uschar *, int,
059ec3d9 432 int, int *);
55414b25
JH
433extern int search_findtype(const uschar *, int);
434extern int search_findtype_partial(const uschar *, int *, const uschar **, int *,
059ec3d9
PH
435 int *);
436extern void *search_open(uschar *, int, int, uid_t *, gid_t *);
437extern void search_tidyup(void);
e0df1c83 438extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2);
5fb822fc
JH
439extern void sha1_end(hctx *, const uschar *, int, uschar *);
440extern void sha1_mid(hctx *, const uschar *);
441extern void sha1_start(hctx *);
e4a89c47 442extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *,
efd9a422 443 uschar *, address_item **, uschar **);
059ec3d9 444extern void sigalrm_handler(int);
58eb016e 445extern BOOL smtp_buffered(void);
059ec3d9 446extern void smtp_closedown(uschar *);
1d1e7973
JH
447extern void smtp_command_timeout_exit(void) NORETURN;
448extern void smtp_command_sigterm_exit(void) NORETURN;
449extern void smtp_data_timeout_exit(void) NORETURN;
450extern void smtp_data_sigint_exit(void) NORETURN;
d85cdeb5 451extern void smtp_deliver_init(void);
a09f2942 452extern uschar *smtp_cmd_hist(void);
ee8b8090 453extern int smtp_connect(smtp_connect_args *, const blob *);
7eb6c37c 454extern int smtp_sock_connect(host_item *, int, int, uschar *,
0ab63f3d 455 transport_instance * tb, int, const blob *);
059ec3d9
PH
456extern int smtp_feof(void);
457extern int smtp_ferror(void);
458extern uschar *smtp_get_connection_info(void);
6f6dedcc 459extern BOOL smtp_get_interface(uschar *, int, address_item *,
059ec3d9
PH
460 uschar **, uschar *);
461extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *);
bd8fbe36 462extern int smtp_getc(unsigned);
0d81dabc 463extern uschar *smtp_getbuf(unsigned *);
584e96c6 464extern void smtp_get_cache(void);
059ec3d9 465extern int smtp_handle_acl_fail(int, int, uschar *, uschar *);
b4ed4da0 466extern void smtp_log_no_mail(void);
4f6ae5c3 467extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL);
1d1e7973 468extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int) NORETURN;
251b9eb4 469extern BOOL smtp_read_response(void *, uschar *, int, int, int);
f3ebb786 470extern void *smtp_reset(void *);
a5bd321b 471extern void smtp_respond(uschar *, int, BOOL, uschar *);
8f128379 472extern void smtp_notquit_exit(uschar *, uschar *, uschar *, ...);
58c30e47 473extern void smtp_port_for_connect(host_item *, int);
059ec3d9
PH
474extern void smtp_send_prohibition_message(int, uschar *);
475extern int smtp_setup_msg(void);
476extern BOOL smtp_start_session(void);
477extern int smtp_ungetc(int);
d7b47fd0 478extern BOOL smtp_verify_helo(void);
251b9eb4 479extern int smtp_write_command(void *, int, const char *, ...) PRINTF_FUNCTION(3,4);
8523533c 480#ifdef WITH_CONTENT_SCAN
55414b25 481extern int spam(const uschar **);
040721f2 482extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **);
8523533c 483#endif
4b4856ff 484extern void spool_clear_header_globals(void);
4b4856ff 485extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *);
789f8a4f 486extern int spool_open_datafile(uschar *);
059ec3d9
PH
487extern int spool_open_temp(uschar *);
488extern int spool_read_header(uschar *, BOOL, BOOL);
489extern int spool_write_header(uschar *, int, uschar **);
bd8fbe36 490extern int stdin_getc(unsigned);
059ec3d9
PH
491extern int stdin_feof(void);
492extern int stdin_ferror(void);
493extern int stdin_ungetc(int);
f3ebb786
JH
494
495extern void store_exit(void);
acec9514
JH
496extern gstring *string_append(gstring *, int, ...) WARN_UNUSED_RESULT;
497extern gstring *string_append_listele(gstring *, uschar, const uschar *) WARN_UNUSED_RESULT;
498extern gstring *string_append_listele_n(gstring *, uschar, const uschar *, unsigned) WARN_UNUSED_RESULT;
bce15b62 499extern gstring *string_append2_listele_n(gstring *, const uschar *, const uschar *, unsigned) WARN_UNUSED_RESULT;
059ec3d9 500extern uschar *string_base62(unsigned long int);
acec9514
JH
501extern gstring *string_cat (gstring *, const uschar * ) WARN_UNUSED_RESULT;
502extern gstring *string_catn(gstring *, const uschar *, int) WARN_UNUSED_RESULT;
84bbb4d8 503extern int string_compare_by_pointer(const void *, const void *);
059ec3d9 504extern uschar *string_copy_dnsdomain(uschar *);
55414b25 505extern uschar *string_copy_malloc(const uschar *);
55414b25 506extern uschar *string_dequote(const uschar **);
059ec3d9 507extern uschar *string_format_size(int, uschar *);
55414b25 508extern int string_interpret_escape(const uschar **);
b1f8e4f8 509extern int string_is_ip_address(const uschar *, int *);
8c5d388a 510#ifdef SUPPORT_I18N
0d7911ea
JH
511extern BOOL string_is_utf8(const uschar *);
512#endif
55414b25 513extern uschar *string_nextinlist(const uschar **, int *, uschar *, int);
55414b25 514extern const uschar *string_printing2(const uschar *, BOOL);
e28326d8 515extern uschar *string_split_message(uschar *);
c7396ac5 516extern uschar *string_unprinting(uschar *);
8c5d388a 517#ifdef SUPPORT_I18N
3c8b3577 518extern uschar *string_address_utf8_to_alabel(const uschar *, uschar **);
0d7911ea
JH
519extern uschar *string_domain_alabel_to_utf8(const uschar *, uschar **);
520extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **);
521extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **);
522extern uschar *string_localpart_utf8_to_alabel(const uschar *, uschar **);
523#endif
f3ebb786
JH
524
525#define string_format(buf, siz, fmt, ...) \
c4efe382 526 string_format_trc(buf, siz, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
f3ebb786
JH
527extern BOOL string_format_trc(uschar *, int, const uschar *, unsigned,
528 const char *, ...) ALMOST_PRINTF(5,6);
529
530#define string_vformat(g, flgs, fmt, ap) \
531 string_vformat_trc(g, US __FUNCTION__, __LINE__, \
532 STRING_SPRINTF_BUFFER_SIZE, flgs, fmt, ap)
533extern gstring *string_vformat_trc(gstring *, const uschar *, unsigned,
534 unsigned, unsigned, const char *, va_list);
535
536#define string_open_failed(eno, fmt, ...) \
c4efe382 537 string_open_failed_trc(eno, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
f3ebb786
JH
538extern uschar *string_open_failed_trc(int, const uschar *, unsigned,
539 const char *, ...) PRINTF_FUNCTION(4,5);
540
1ba28e2b
PP
541extern int strcmpic(const uschar *, const uschar *);
542extern int strncmpic(const uschar *, const uschar *, int);
059ec3d9
PH
543extern uschar *strstric(uschar *, uschar *, BOOL);
544
44416341 545extern int test_harness_fudged_queue_time(int);
d85cdeb5 546extern void tcp_init(void);
10ac8d7f
JH
547#ifdef EXIM_TFO_PROBE
548extern void tfo_probe(void);
549#endif
32dfdf8b 550extern void tls_modify_variables(tls_support *);
059ec3d9 551extern uschar *tod_stamp(int);
41afb5cb 552
55414b25 553extern BOOL transport_check_waiting(const uschar *, const uschar *, int, uschar *,
a39bd74d 554 BOOL *, oicf, void*);
059ec3d9 555extern void transport_init(void);
57cc2785
JH
556extern void transport_do_pass_socket(const uschar *, const uschar *,
557 const uschar *, uschar *, int);
55414b25 558extern BOOL transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *,
059ec3d9
PH
559 int);
560extern uschar *transport_rcpt_address(address_item *, BOOL);
55414b25
JH
561extern BOOL transport_set_up_command(const uschar ***, uschar *,
562 BOOL, int, address_item *, uschar *, uschar **);
059ec3d9 563extern void transport_update_waiting(host_item *, uschar *);
42055a33
JH
564extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL);
565extern void transport_write_reset(int);
1ba28e2b 566extern BOOL transport_write_string(int, const char *, ...);
42055a33
JH
567extern BOOL transport_headers_send(transport_ctx *,
568 BOOL (*)(transport_ctx *, uschar *, int));
adf73d37 569extern void transport_show_supported(FILE *);
42055a33 570extern BOOL transport_write_message(transport_ctx *, int);
059ec3d9
PH
571extern void tree_add_duplicate(uschar *, address_item *);
572extern void tree_add_nonrecipient(uschar *);
573extern void tree_add_unusable(host_item *);
b4f579d1 574extern void tree_dup(tree_node **, tree_node *);
059ec3d9 575extern int tree_insertnode(tree_node **, tree_node *);
55414b25 576extern tree_node *tree_search(tree_node *, const uschar *);
059ec3d9 577extern void tree_write(tree_node *, FILE *);
38a0a95f 578extern void tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *);
059ec3d9 579
8523533c
TK
580#ifdef WITH_CONTENT_SCAN
581extern void unspool_mbox(void);
582#endif
8c5d388a 583#ifdef SUPPORT_I18N
fc362fc5
JH
584extern void utf8_version_report(FILE *);
585#endif
8523533c 586
4deaf07d
PH
587extern int verify_address(address_item *, FILE *, int, int, int, int,
588 uschar *, uschar *, BOOL *);
379ba7d0 589extern int verify_check_dnsbl(int, const uschar **, uschar **);
4deaf07d 590extern int verify_check_header_address(uschar **, uschar **, int, int, int,
fe5b5d0b 591 uschar *, uschar *, int, int *);
059ec3d9 592extern int verify_check_headers(uschar **);
770747fd 593extern int verify_check_header_names_ascii(uschar **);
059ec3d9 594extern int verify_check_host(uschar **);
7c498df1 595extern int verify_check_notblind(BOOL);
3fb3231c 596extern int verify_check_given_host(const uschar **, const host_item *);
55414b25
JH
597extern int verify_check_this_host(const uschar **, unsigned int *,
598 const uschar*, const uschar *, const uschar **);
059ec3d9
PH
599extern address_item *verify_checked_sender(uschar *);
600extern void verify_get_ident(int);
601extern BOOL verify_sender(int *, uschar **);
602extern BOOL verify_sender_preliminary(int *, uschar **);
603extern void version_init(void);
604
42055a33 605extern BOOL write_chunk(transport_ctx *, uschar *, int);
17c76198
PP
606extern ssize_t write_to_fd_buf(int, const uschar *, size_t);
607
6940b3df 608
7172970e 609#if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
b66fecb4 610/* exim_chown - in some NFSv4 setups *seemes* to be an issue with
6940b3df 611chown(<exim-uid>, <exim-gid>).
b66fecb4 612
6940b3df
JH
613Probably because the idmapping is broken, misconfigured or set up in
614an unusal way. (see Bug 2931). As I'm not sure, if this was a single
615case of misconfiguration, or if there are more such broken systems
616out, I try to impose as least impact as possible and for now just write
617a panic log entry pointing to the bug report. You're encouraged to
618contact the developers, if you experience this issue.
b66fecb4 619
6940b3df
JH
620fd the file descriptor (or -1 if not valid)
621name the file name for error messages or for file operations,
622 if fd is < 0
623owner the owner
624group the group
b66fecb4 625
6940b3df 626returns 0 on success, -1 on failure */
b66fecb4 627
6940b3df 628static inline int
b66fecb4
HSHR
629exim_fchown(int fd, uid_t owner, gid_t group, const uschar *name)
630{
6940b3df
JH
631return fchown(fd, owner, group)
632 ? exim_chown_failure(fd, name, owner, group) : 0;
b66fecb4
HSHR
633}
634
6940b3df 635static inline int
b66fecb4
HSHR
636exim_chown(const uschar *name, uid_t owner, gid_t group)
637{
6940b3df
JH
638return chown(CCS name, owner, group)
639 ? exim_chown_failure(-1, name, owner, group) : 0;
b66fecb4 640}
e59797e3
JH
641
642#endif /* !MACRO_PREDEF && !COMPILE_UTILITY */
643/******************************************************************************/
644/* String functions */
645
f3ebb786 646#if !defined(MACRO_PREDEF)
e59797e3
JH
647/*************************************************
648* Copy and save string *
649*************************************************/
650
651/* This function assumes that memcpy() is faster than strcpy().
652*/
653
e59797e3 654static inline uschar *
f3ebb786 655string_copy_taint_trc(const uschar *s, BOOL tainted, const char * func, int line)
e59797e3
JH
656{
657int len = Ustrlen(s) + 1;
f3ebb786 658uschar *ss = store_get_3(len, tainted, func, line);
e59797e3
JH
659memcpy(ss, s, len);
660return ss;
661}
662
f3ebb786
JH
663#define string_copy_taint(s, tainted) \
664 string_copy_taint_trc((s), tainted, __FUNCTION__, __LINE__)
665
666static inline uschar *
667string_copy(const uschar * s)
668{
669return string_copy_taint((s), is_tainted(s));
670}
671
e59797e3
JH
672
673/*************************************************
674* Copy, lowercase and save string *
675*************************************************/
676
677/*
678Argument: string to copy
679Returns: copy of string in new store, with letters lowercased
680*/
681
682static inline uschar *
683string_copylc(const uschar *s)
684{
f3ebb786 685uschar *ss = store_get(Ustrlen(s) + 1, is_tainted(s));
e59797e3
JH
686uschar *p = ss;
687while (*s != 0) *p++ = tolower(*s++);
688*p = 0;
689return ss;
690}
691
692
693
694/*************************************************
695* Copy and save string, given length *
696*************************************************/
697
698/* It is assumed the data contains no zeros. A zero is added
699onto the end.
700
701Arguments:
702 s string to copy
703 n number of characters
704
705Returns: copy of string in new store
706
707This is an API for local_scan hence not static.
708*/
709
710static inline uschar *
711string_copyn(const uschar *s, int n)
712{
f3ebb786 713uschar *ss = store_get(n + 1, is_tainted(s));
e59797e3
JH
714Ustrncpy(ss, s, n);
715ss[n] = 0;
716return ss;
717}
718
719/*************************************************
720* Copy, lowercase, and save string, given length *
721*************************************************/
722
723/* It is assumed the data contains no zeros. A zero is added
724onto the end.
725
726Arguments:
727 s string to copy
728 n number of characters
729
730Returns: copy of string in new store, with letters lowercased
731*/
732
733static inline uschar *
734string_copynlc(uschar *s, int n)
735{
f3ebb786 736uschar *ss = store_get(n + 1, is_tainted(s));
e59797e3
JH
737uschar *p = ss;
738while (n-- > 0) *p++ = tolower(*s++);
739*p = 0;
740return ss;
741}
742
743
1a44d9d7 744# ifndef COMPILE_UTILITY
f3ebb786
JH
745/*************************************************
746* Copy and save string in longterm store *
747*************************************************/
748
749/* This function assumes that memcpy() is faster than strcpy().
750
751Argument: string to copy
752Returns: copy of string in new store
753*/
754
755static inline uschar *
756string_copy_perm(const uschar *s, BOOL force_taint)
757{
758int old_pool = store_pool;
759int len = Ustrlen(s) + 1;
760uschar *ss;
761
762store_pool = POOL_PERM;
763ss = store_get(len, force_taint || is_tainted(s));
764memcpy(ss, s, len);
765store_pool = old_pool;
766return ss;
767}
1a44d9d7 768# endif
f3ebb786
JH
769
770
771
772/* sprintf into a buffer, taint-unchecked */
773
774static inline void
775string_format_nt(uschar * buf, int siz, const char * fmt, ...)
776{
777gstring gs = { .size = siz, .ptr = 0, .s = buf };
778va_list ap;
779va_start(ap, fmt);
780(void) string_vformat(&gs, SVFMT_TAINT_NOCHK, fmt, ap);
781va_end(ap);
782}
783
784
785
e59797e3
JH
786/******************************************************************************/
787/* Growable-string functions */
788
f3ebb786
JH
789/* Create a growable-string with some preassigned space */
790
791#define string_get_tainted(size, tainted) \
792 string_get_tainted_trc((size), (tainted), __FUNCTION__, __LINE__)
e59797e3
JH
793
794static inline gstring *
f3ebb786 795string_get_tainted_trc(unsigned size, BOOL tainted, const char * func, unsigned line)
e59797e3 796{
f3ebb786 797gstring * g = store_get_3(sizeof(gstring) + size, tainted, func, line);
e59797e3
JH
798g->size = size;
799g->ptr = 0;
800g->s = US(g + 1);
801return g;
802}
803
f3ebb786
JH
804#define string_get(size) \
805 string_get_trc((size), __FUNCTION__, __LINE__)
806
807static inline gstring *
808string_get_trc(unsigned size, const char * func, unsigned line)
809{
810return string_get_tainted_trc(size, FALSE, func, line);
811}
812
e59797e3
JH
813/* NUL-terminate the C string in the growable-string, and return it. */
814
815static inline uschar *
816string_from_gstring(gstring * g)
817{
818if (!g) return NULL;
819g->s[g->ptr] = '\0';
820return g->s;
821}
822
ba5120a4
JH
823static inline unsigned
824gstring_length(const gstring * g)
825{
826return g ? (unsigned)g->ptr : 0;
827}
828
f3ebb786
JH
829
830#define gstring_release_unused(g) \
831 gstring_release_unused_trc(g, __FUNCTION__, __LINE__)
832
e59797e3 833static inline void
f3ebb786 834gstring_release_unused_trc(gstring * g, const char * file, unsigned line)
e59797e3 835{
f3ebb786
JH
836if (g) store_release_above_3(g->s + (g->size = g->ptr + 1), file, line);
837}
838
839
840/* sprintf-append to a growable-string */
841
842#define string_fmt_append(g, fmt, ...) \
843 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
c4efe382 844 SVFMT_EXTEND|SVFMT_REBUFFER, fmt, __VA_ARGS__)
f3ebb786
JH
845
846#define string_fmt_append_f(g, flgs, fmt, ...) \
847 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
c4efe382 848 flgs, fmt, __VA_ARGS__)
f3ebb786
JH
849
850static inline gstring *
851string_fmt_append_f_trc(gstring * g, const uschar * func, unsigned line,
852 unsigned flags, const char *format, ...)
853{
854va_list ap;
855va_start(ap, format);
856g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
857 flags, format, ap);
858va_end(ap);
859return g;
e59797e3
JH
860}
861
862/******************************************************************************/
8743d3ac
JH
863
864#define store_get_dns_answer() store_get_dns_answer_trc(CUS __FUNCTION__, __LINE__)
865
866static inline dns_answer *
867store_get_dns_answer_trc(const uschar * func, unsigned line)
868{
869return store_get_3(sizeof(dns_answer), TRUE, CCS func, line); /* use tainted mem */
870}
871
59a93276
JH
872/******************************************************************************/
873/* Routines with knowledge of spool layout */
874
875# ifndef COMPILE_UTILITY
876static inline void
877spool_pname_buf(uschar * buf, int len)
878{
879snprintf(CS buf, len, "%s/%s/input", spool_directory, queue_name);
880}
881
882static inline uschar *
883spool_dname(const uschar * purpose, uschar * subdir)
884{
885return string_sprintf("%s/%s/%s/%s",
886 spool_directory, queue_name, purpose, subdir);
887}
888# endif
889
890static inline uschar *
fc7bae7f 891spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir)
59a93276
JH
892{
893return string_sprintf("%s%s%s%s%s",
fc7bae7f 894 q, *q ? "/" : "",
59a93276
JH
895 purpose,
896 *subdir ? "/" : "", subdir);
897}
898
fc7bae7f
JH
899static inline uschar *
900spool_sname(const uschar * purpose, uschar * subdir)
901{
902return spool_q_sname(purpose, queue_name, subdir);
903}
904
905static inline uschar *
906spool_q_fname(const uschar * purpose, const uschar * q,
907 const uschar * subdir, const uschar * fname, const uschar * suffix)
908{
909return string_sprintf("%s/%s/%s/%s/%s%s",
910 spool_directory, q, purpose, subdir, fname, suffix);
911}
912
59a93276
JH
913static inline uschar *
914spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
8aa16eb7 915 const uschar * suffix)
59a93276 916{
8aa16eb7
JH
917#ifdef COMPILE_UTILITY /* version avoiding string-extension */
918int len = Ustrlen(spool_directory) + 1 + Ustrlen(queue_name) + 1 + Ustrlen(purpose) + 1
919 + Ustrlen(subdir) + 1 + Ustrlen(fname) + Ustrlen(suffix) + 1;
920uschar * buf = store_get(len, FALSE);
921string_format(buf, len, "%s/%s/%s/%s/%s%s",
922 spool_directory, queue_name, purpose, subdir, fname, suffix);
923return buf;
924#else
fc7bae7f 925return spool_q_fname(purpose, queue_name, subdir, fname, suffix);
8aa16eb7 926#endif
59a93276
JH
927}
928
9b62f401 929static inline void
59a93276
JH
930set_subdir_str(uschar * subdir_str, const uschar * name,
931 int search_sequence)
932{
933subdir_str[0] = split_spool_directory == (search_sequence == 0)
934 ? name[5] : '\0';
935subdir_str[1] = '\0';
936}
937
938/******************************************************************************/
9e21ce8f
JH
939/* Time calculations */
940
9f01e50d 941static inline void
a55697ac 942timesince(struct timeval * diff, const struct timeval * then)
9f01e50d
JH
943{
944gettimeofday(diff, NULL);
945diff->tv_sec -= then->tv_sec;
946if ((diff->tv_usec -= then->tv_usec) < 0)
947 {
948 diff->tv_sec--;
949 diff->tv_usec += 1000*1000;
950 }
951}
952
953static inline uschar *
a55697ac 954string_timediff(const struct timeval * diff)
9f01e50d
JH
955{
956static uschar buf[sizeof("0.000s")];
957
958if (diff->tv_sec >= 5 || !LOGGING(millisec))
959 return readconf_printtime((int)diff->tv_sec);
960
b09c5f34 961snprintf(CS buf, sizeof(buf), "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
9f01e50d
JH
962return buf;
963}
964
965
966static inline uschar *
a55697ac 967string_timesince(const struct timeval * then)
9f01e50d
JH
968{
969struct timeval diff;
970timesince(&diff, then);
971return string_timediff(&diff);
972}
973
974static inline void
a55697ac 975report_time_since(const struct timeval * t0, const uschar * where)
9f01e50d
JH
976{
977# ifdef MEASURE_TIMING
978struct timeval diff;
979timesince(&diff, t0);
980fprintf(stderr, "%d %s:\t%ld.%06ld\n",
981 (uint)getpid(), where, (long)diff.tv_sec, (long)diff.tv_usec);
982# endif
983}
984
985
986static inline void
987testharness_pause_ms(int millisec)
988{
989#ifndef MEASURE_TIMING
990if (f.running_in_test_harness) millisleep(millisec);
991#endif
992}
993
9e21ce8f
JH
994/******************************************************************************/
995/* Taint-checked file opens */
996
997static inline int
998exim_open2(const char *pathname, int flags)
999{
1000if (!is_tainted(pathname)) return open(pathname, flags);
1001log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1002errno = EACCES;
1003return -1;
1004}
1005static inline int
1006exim_open(const char *pathname, int flags, mode_t mode)
1007{
1008if (!is_tainted(pathname)) return open(pathname, flags, mode);
1009log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1010errno = EACCES;
1011return -1;
1012}
1013static inline int
1014exim_openat(int dirfd, const char *pathname, int flags)
1015{
1016if (!is_tainted(pathname)) return openat(dirfd, pathname, flags);
1017log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1018errno = EACCES;
1019return -1;
1020}
1021static inline int
1022exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
1023{
1024if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode);
1025log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1026errno = EACCES;
1027return -1;
1028}
1029
1030static inline FILE *
1031exim_fopen(const char *pathname, const char *mode)
1032{
1033if (!is_tainted(pathname)) return fopen(pathname, mode);
1034log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1035errno = EACCES;
1036return NULL;
1037}
1038
eb2fb50d 1039#endif /* !MACRO_PREDEF */
b66fecb4
HSHR
1040
1041#endif /* _FUNCTIONS_H_ */
acec9514 1042
9d1c15ef
JH
1043/* vi: aw
1044*/
059ec3d9 1045/* End of functions.h */