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