Debug: internal consistency under testsuite
[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 */
f42deca9 245extern uschar *expand_hide_passwords(uschar * );
55414b25 246extern uschar *expand_string_copy(const uschar *);
97d17305 247extern int_eximarith_t expand_string_integer(uschar *, BOOL);
d9b2312b 248extern void modify_variable(uschar *, void *);
059ec3d9 249
0a5441fc 250extern BOOL fd_ready(int, time_t);
4e71661f 251
059ec3d9
PH
252extern int filter_interpret(uschar *, int, address_item **, uschar **);
253extern BOOL filter_personal(string_item *, BOOL);
f05da2e8 254extern BOOL filter_runtest(int, uschar *, BOOL, BOOL);
059ec3d9
PH
255extern BOOL filter_system_interpret(address_item **, uschar **);
256
362145b5
JH
257extern uschar * fn_hdrs_added(void);
258
1ba28e2b 259extern void header_add(int, const char *, ...);
049782c0 260extern header_line *header_add_at_position_internal(BOOL, uschar *, BOOL, int, const char *, ...);
059ec3d9
PH
261extern int header_checkname(header_line *, BOOL);
262extern BOOL header_match(uschar *, BOOL, BOOL, string_item *, int, ...);
7cd1141b 263extern int host_address_extract_port(uschar *);
059ec3d9 264extern uschar *host_and_ident(BOOL);
55414b25
JH
265extern int host_aton(const uschar *, int *);
266extern void host_build_hostlist(host_item **, const uschar *, BOOL);
267extern ip_address_item *host_build_ifacelist(const uschar *, uschar *);
059ec3d9
PH
268extern void host_build_log_info(void);
269extern void host_build_sender_fullhost(void);
a207d5dd 270extern int host_find_byname(host_item *, const uschar *, int,
1f155f8e 271 const uschar **, BOOL);
55414b25 272extern int host_find_bydns(host_item *, const uschar *, int, uschar *, uschar *,
7cd171b7 273 uschar *, const dnssec_domains *, const uschar **, BOOL *);
059ec3d9 274extern ip_address_item *host_find_interfaces(void);
55414b25 275extern BOOL host_is_in_net(const uschar *, const uschar *, int);
059ec3d9 276extern BOOL host_is_tls_on_connect_port(int);
7cd1141b 277extern int host_item_get_port(host_item *);
059ec3d9
PH
278extern void host_mask(int, int *, int);
279extern int host_name_lookup(void);
6f0c9a4f 280extern int host_nmtoa(int, int *, int, uschar *, int);
059ec3d9
PH
281extern uschar *host_ntoa(int, const void *, uschar *, int *);
282extern int host_scan_for_local_hosts(host_item *, host_item **, BOOL *);
283
94431adb 284extern uschar *imap_utf7_encode(uschar *, const uschar *,
ed0512a1
JH
285 uschar, uschar *, uschar **);
286
83e029d5 287extern void invert_address(uschar *, uschar *);
7eb6c37c 288extern int ip_addr(void *, int, const uschar *, int);
059ec3d9 289extern int ip_bind(int, int, uschar *, int);
0ab63f3d 290extern int ip_connect(int, int, const uschar *, int, int, const blob *);
b1f8e4f8 291extern int ip_connectedsocket(int, const uschar *, int, int,
4a5cbaff 292 int, host_item *, uschar **, const blob *);
13363eba 293extern int ip_get_address_family(int);
55414b25 294extern void ip_keepalive(int, const uschar *, BOOL);
0a5441fc 295extern int ip_recv(client_conn_ctx *, uschar *, int, time_t);
059ec3d9
PH
296extern int ip_socket(int, int);
297
7d2f2d36 298extern int ip_tcpsocket(const uschar *, uschar **, int, host_item *);
3e60dd41 299extern int ip_unixsocket(const uschar *, uschar **);
7d2f2d36 300extern int ip_streamsocket(const uschar *, uschar **, int, host_item *);
3e60dd41 301
fc4a7f70
JH
302extern int ipv6_nmtoa(int *, uschar *);
303
921b12ca 304extern uschar *local_part_quote(uschar *);
4840604e 305extern int log_create(uschar *);
921b12ca 306extern int log_create_as_exim(uschar *);
059ec3d9
PH
307extern void log_close_all(void);
308
d185889f 309extern macro_item * macro_create(const uschar *, const uschar *, BOOL);
c246a1de
JH
310extern BOOL macro_read_assignment(uschar *);
311extern uschar *macros_expand(int, int *, BOOL *);
9cd319d9 312extern void mainlog_close(void);
8523533c 313#ifdef WITH_CONTENT_SCAN
0f0c8159 314extern int malware(const uschar *, int);
dbc4b90d 315extern int malware_in_file(uschar *);
476be7e2 316extern void malware_init(void);
ab1604ea 317extern gstring * malware_show_supported(gstring *);
8523533c 318#endif
55414b25
JH
319extern int match_address_list(const uschar *, BOOL, BOOL, const uschar **,
320 unsigned int *, int, int, const uschar **);
36d295f1 321extern int match_address_list_basic(const uschar *, const uschar **, int);
55414b25
JH
322extern int match_check_list(const uschar **, int, tree_node **, unsigned int **,
323 int(*)(void *, const uschar *, const uschar **, uschar **), void *, int,
324 const uschar *, const uschar **);
325extern int match_isinlist(const uschar *, const uschar **, int, tree_node **,
326 unsigned int *, int, BOOL, const uschar **);
327extern int match_check_string(const uschar *, const uschar *, int, BOOL, BOOL, BOOL,
328 const uschar **);
059ec3d9
PH
329extern void md5_end(md5 *, const uschar *, int, uschar *);
330extern void md5_mid(md5 *, const uschar *);
331extern void md5_start(md5 *);
332extern void millisleep(int);
8523533c
TK
333#ifdef WITH_CONTENT_SCAN
334struct mime_boundary_context;
54cdb463
PH
335extern int mime_acl_check(uschar *acl, FILE *f,
336 struct mime_boundary_context *, uschar **, uschar **);
55414b25 337extern int mime_decode(const uschar **);
f4d091fb 338extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *);
55414b25 339extern int mime_regex(const uschar **);
f4d091fb 340extern void mime_set_anomaly(int);
8523533c 341#endif
059ec3d9
PH
342extern uschar *moan_check_errorcopy(uschar *);
343extern BOOL moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
344 BOOL, uschar *);
e0df1c83 345extern void moan_smtp_batch(uschar *, const char *, ...) PRINTF_FUNCTION(2,3);
5455f548
JH
346extern BOOL moan_send_message(uschar *, int, error_block *eblock,
347 header_line *, FILE *, uschar *);
1ba28e2b 348extern void moan_tell_someone(uschar *, address_item *,
e0df1c83 349 const uschar *, const char *, ...) PRINTF_FUNCTION(4,5);
059ec3d9 350extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
0e22dfd1 351extern void moan_write_from(FILE *);
d6c829b9 352extern void moan_write_references(FILE *, uschar *);
1ba28e2b 353extern FILE *modefopen(const uschar *, const char *, mode_t);
059ec3d9 354
f9334a28 355extern int open_cutthrough_connection( address_item * addr );
e4bdf652 356
059ec3d9
PH
357extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
358 BOOL);
359extern int parse_forward_list(uschar *, int, address_item **, uschar **,
55414b25 360 const uschar *, uschar *, error_block **);
059ec3d9
PH
361extern uschar *parse_find_address_end(uschar *, BOOL);
362extern uschar *parse_find_at(uschar *);
55414b25 363extern const uschar *parse_fix_phrase(const uschar *, int, uschar *, int);
30dba1e6 364extern uschar *parse_message_id(uschar *, uschar **, uschar **);
55414b25 365extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL);
43ad7b7d 366extern uschar *parse_date_time(uschar *str, time_t *t);
17c76198 367extern int vaguely_random_number(int);
01603eec 368#ifndef DISABLE_TLS
17c76198
PP
369extern int vaguely_random_number_fallback(int);
370#endif
059ec3d9
PH
371
372extern BOOL queue_action(uschar *, int, uschar **, int, int);
373extern void queue_check_only(void);
04403ab0
JH
374extern unsigned queue_count(void);
375extern unsigned queue_count_cached(void);
ff966302
JH
376extern void queue_list(int, uschar **, int);
377#ifdef EXPERIMENTAL_QUEUE_RAMP
378extern void queue_notify_daemon(const uschar * hostname);
379#endif
059ec3d9
PH
380extern void queue_run(uschar *, uschar *, BOOL);
381
382extern int random_number(int);
aeb65e91 383extern const uschar *rc_to_string(int);
e4a89c47 384extern int rda_interpret(redirect_block *, int, uschar *, uschar *,
efd9a422
MH
385 uschar *, uschar *, uschar *, ugid_block *, address_item **,
386 uschar **, error_block **, int *, uschar *);
059ec3d9
PH
387extern int rda_is_filter(const uschar *);
388extern BOOL readconf_depends(driver_instance *, uschar *);
389extern void readconf_driver_init(uschar *, driver_instance **,
390 driver_info *, int, void *, int, optionlist *, int);
391extern uschar *readconf_find_option(void *);
34e86e20 392extern void readconf_main(BOOL);
383832ef 393extern void readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *);
2be324ee 394extern BOOL readconf_print(uschar *, uschar *, BOOL);
059ec3d9
PH
395extern uschar *readconf_printtime(int);
396extern uschar *readconf_readname(uschar *, int, uschar *);
1ad6489e 397extern int readconf_readtime(const uschar *, int, BOOL);
bf3c2c6b 398extern void readconf_rest(void);
55414b25 399extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *);
bf3c2c6b 400extern void readconf_save_config(const uschar *);
328895cc 401extern void read_message_body(BOOL);
1d1e7973 402extern void receive_bomb_out(uschar *, uschar *) NORETURN;
059ec3d9
PH
403extern BOOL receive_check_fs(int);
404extern BOOL receive_check_set_sender(uschar *);
405extern BOOL receive_msg(BOOL);
a45431fa 406extern int_eximarith_t receive_statvfs(BOOL, int *);
059ec3d9 407extern void receive_swallow_smtp(void);
8523533c 408#ifdef WITH_CONTENT_SCAN
55414b25 409extern int regex(const uschar **);
8523533c 410#endif
1dc92d5a 411extern BOOL regex_match_and_setup(const pcre *, const uschar *, int, int);
476be7e2 412extern const pcre *regex_must_compile(const uschar *, BOOL, BOOL);
059ec3d9 413extern void retry_add_item(address_item *, uschar *, int);
55414b25 414extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL,
059ec3d9 415 uschar **, uschar **);
55414b25
JH
416extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
417extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *,
ba9af0af 418 dbdata_retry *, time_t);
059ec3d9
PH
419extern void retry_update(address_item **, address_item **, address_item **);
420extern uschar *rewrite_address(uschar *, BOOL, BOOL, rewrite_rule *, int);
421extern uschar *rewrite_address_qualify(uschar *, BOOL);
55414b25
JH
422extern header_line *rewrite_header(header_line *,
423 const uschar *, const uschar *,
059ec3d9
PH
424 rewrite_rule *, int, BOOL);
425extern uschar *rewrite_one(uschar *, int, BOOL *, BOOL, uschar *,
426 rewrite_rule *);
427extern void rewrite_test(uschar *);
428extern uschar *rfc2047_decode2(uschar *, BOOL, uschar *, int, int *, int *,
429 uschar **);
430extern int route_address(address_item *, address_item **, address_item **,
431 address_item **, address_item **, int);
759502e5
JH
432extern int route_check_prefix(const uschar *, const uschar *, unsigned *);
433extern int route_check_suffix(const uschar *, const uschar *, unsigned *);
059ec3d9 434extern BOOL route_findgroup(uschar *, gid_t *);
55414b25 435extern BOOL route_finduser(const uschar *, struct passwd **, uid_t *);
059ec3d9
PH
436extern BOOL route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
437 uschar **);
438extern BOOL route_find_expanded_user(uschar *, uschar *, uschar *,
439 struct passwd **, uid_t *, uschar **);
440extern void route_init(void);
ab1604ea 441extern gstring * route_show_supported(gstring *);
059ec3d9
PH
442extern void route_tidyup(void);
443
d447dbd1 444extern uschar *search_find(void *, const uschar *, uschar *, int,
67a57a5a 445 const uschar *, int, int, int *, const uschar *);
55414b25
JH
446extern int search_findtype(const uschar *, int);
447extern int search_findtype_partial(const uschar *, int *, const uschar **, int *,
67a57a5a 448 int *, const uschar **);
d447dbd1 449extern void *search_open(const uschar *, int, int, uid_t *, gid_t *);
059ec3d9 450extern void search_tidyup(void);
e0df1c83 451extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2);
5fb822fc
JH
452extern void sha1_end(hctx *, const uschar *, int, uschar *);
453extern void sha1_mid(hctx *, const uschar *);
454extern void sha1_start(hctx *);
e4a89c47 455extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *,
efd9a422 456 uschar *, address_item **, uschar **);
059ec3d9 457extern void sigalrm_handler(int);
58eb016e 458extern BOOL smtp_buffered(void);
059ec3d9 459extern void smtp_closedown(uschar *);
1d1e7973
JH
460extern void smtp_command_timeout_exit(void) NORETURN;
461extern void smtp_command_sigterm_exit(void) NORETURN;
462extern void smtp_data_timeout_exit(void) NORETURN;
463extern void smtp_data_sigint_exit(void) NORETURN;
d85cdeb5 464extern void smtp_deliver_init(void);
a09f2942 465extern uschar *smtp_cmd_hist(void);
ee8b8090 466extern int smtp_connect(smtp_connect_args *, const blob *);
7eb6c37c 467extern int smtp_sock_connect(host_item *, int, int, uschar *,
0ab63f3d 468 transport_instance * tb, int, const blob *);
059ec3d9
PH
469extern int smtp_feof(void);
470extern int smtp_ferror(void);
471extern uschar *smtp_get_connection_info(void);
6f6dedcc 472extern BOOL smtp_get_interface(uschar *, int, address_item *,
059ec3d9
PH
473 uschar **, uschar *);
474extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *);
bd8fbe36 475extern int smtp_getc(unsigned);
0d81dabc 476extern uschar *smtp_getbuf(unsigned *);
584e96c6 477extern void smtp_get_cache(void);
059ec3d9 478extern int smtp_handle_acl_fail(int, int, uschar *, uschar *);
b4ed4da0 479extern void smtp_log_no_mail(void);
4f6ae5c3 480extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL);
1d1e7973 481extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int) NORETURN;
251b9eb4 482extern BOOL smtp_read_response(void *, uschar *, int, int, int);
f3ebb786 483extern void *smtp_reset(void *);
a5bd321b 484extern void smtp_respond(uschar *, int, BOOL, uschar *);
8f128379 485extern void smtp_notquit_exit(uschar *, uschar *, uschar *, ...);
58c30e47 486extern void smtp_port_for_connect(host_item *, int);
059ec3d9
PH
487extern void smtp_send_prohibition_message(int, uschar *);
488extern int smtp_setup_msg(void);
489extern BOOL smtp_start_session(void);
490extern int smtp_ungetc(int);
d7b47fd0 491extern BOOL smtp_verify_helo(void);
251b9eb4 492extern int smtp_write_command(void *, int, const char *, ...) PRINTF_FUNCTION(3,4);
8523533c 493#ifdef WITH_CONTENT_SCAN
55414b25 494extern int spam(const uschar **);
040721f2 495extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **);
8523533c 496#endif
4b4856ff 497extern void spool_clear_header_globals(void);
4b4856ff 498extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *);
789f8a4f 499extern int spool_open_datafile(uschar *);
059ec3d9
PH
500extern int spool_open_temp(uschar *);
501extern int spool_read_header(uschar *, BOOL, BOOL);
502extern int spool_write_header(uschar *, int, uschar **);
bd8fbe36 503extern int stdin_getc(unsigned);
059ec3d9
PH
504extern int stdin_feof(void);
505extern int stdin_ferror(void);
506extern int stdin_ungetc(int);
f3ebb786
JH
507
508extern void store_exit(void);
acec9514
JH
509extern gstring *string_append(gstring *, int, ...) WARN_UNUSED_RESULT;
510extern gstring *string_append_listele(gstring *, uschar, const uschar *) WARN_UNUSED_RESULT;
511extern gstring *string_append_listele_n(gstring *, uschar, const uschar *, unsigned) WARN_UNUSED_RESULT;
bce15b62 512extern gstring *string_append2_listele_n(gstring *, const uschar *, const uschar *, unsigned) WARN_UNUSED_RESULT;
059ec3d9 513extern uschar *string_base62(unsigned long int);
acec9514
JH
514extern gstring *string_cat (gstring *, const uschar * ) WARN_UNUSED_RESULT;
515extern gstring *string_catn(gstring *, const uschar *, int) WARN_UNUSED_RESULT;
84bbb4d8 516extern int string_compare_by_pointer(const void *, const void *);
059ec3d9 517extern uschar *string_copy_dnsdomain(uschar *);
55414b25 518extern uschar *string_copy_malloc(const uschar *);
55414b25 519extern uschar *string_dequote(const uschar **);
059ec3d9 520extern uschar *string_format_size(int, uschar *);
55414b25 521extern int string_interpret_escape(const uschar **);
b1f8e4f8 522extern int string_is_ip_address(const uschar *, int *);
8c5d388a 523#ifdef SUPPORT_I18N
0d7911ea
JH
524extern BOOL string_is_utf8(const uschar *);
525#endif
55414b25 526extern const uschar *string_printing2(const uschar *, BOOL);
e28326d8 527extern uschar *string_split_message(uschar *);
c7396ac5 528extern uschar *string_unprinting(uschar *);
8c5d388a 529#ifdef SUPPORT_I18N
3c8b3577 530extern uschar *string_address_utf8_to_alabel(const uschar *, uschar **);
0d7911ea
JH
531extern uschar *string_domain_alabel_to_utf8(const uschar *, uschar **);
532extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **);
533extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **);
534extern uschar *string_localpart_utf8_to_alabel(const uschar *, uschar **);
535#endif
f3ebb786
JH
536
537#define string_format(buf, siz, fmt, ...) \
c4efe382 538 string_format_trc(buf, siz, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
f3ebb786
JH
539extern BOOL string_format_trc(uschar *, int, const uschar *, unsigned,
540 const char *, ...) ALMOST_PRINTF(5,6);
541
542#define string_vformat(g, flgs, fmt, ap) \
543 string_vformat_trc(g, US __FUNCTION__, __LINE__, \
544 STRING_SPRINTF_BUFFER_SIZE, flgs, fmt, ap)
545extern gstring *string_vformat_trc(gstring *, const uschar *, unsigned,
546 unsigned, unsigned, const char *, va_list);
547
548#define string_open_failed(eno, fmt, ...) \
c4efe382 549 string_open_failed_trc(eno, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
f3ebb786
JH
550extern uschar *string_open_failed_trc(int, const uschar *, unsigned,
551 const char *, ...) PRINTF_FUNCTION(4,5);
552
ba74fb8d
JH
553#define string_nextinlist(lp, sp, b, l) \
554 string_nextinlist_trc((lp), (sp), (b), (l), US __FUNCTION__, __LINE__)
555extern uschar *string_nextinlist_trc(const uschar **listptr, int *separator, uschar *buffer, int buflen,
556 const uschar * func, int line);
557
1ba28e2b
PP
558extern int strcmpic(const uschar *, const uschar *);
559extern int strncmpic(const uschar *, const uschar *, int);
059ec3d9
PH
560extern uschar *strstric(uschar *, uschar *, BOOL);
561
44416341 562extern int test_harness_fudged_queue_time(int);
d85cdeb5 563extern void tcp_init(void);
10ac8d7f
JH
564#ifdef EXIM_TFO_PROBE
565extern void tfo_probe(void);
566#endif
32dfdf8b 567extern void tls_modify_variables(tls_support *);
059ec3d9 568extern uschar *tod_stamp(int);
41afb5cb 569
55414b25 570extern BOOL transport_check_waiting(const uschar *, const uschar *, int, uschar *,
a39bd74d 571 BOOL *, oicf, void*);
059ec3d9 572extern void transport_init(void);
57cc2785
JH
573extern void transport_do_pass_socket(const uschar *, const uschar *,
574 const uschar *, uschar *, int);
55414b25 575extern BOOL transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *,
059ec3d9
PH
576 int);
577extern uschar *transport_rcpt_address(address_item *, BOOL);
55414b25
JH
578extern BOOL transport_set_up_command(const uschar ***, uschar *,
579 BOOL, int, address_item *, uschar *, uschar **);
059ec3d9 580extern void transport_update_waiting(host_item *, uschar *);
42055a33
JH
581extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL);
582extern void transport_write_reset(int);
1ba28e2b 583extern BOOL transport_write_string(int, const char *, ...);
42055a33
JH
584extern BOOL transport_headers_send(transport_ctx *,
585 BOOL (*)(transport_ctx *, uschar *, int));
ab1604ea 586extern gstring * transport_show_supported(gstring *);
42055a33 587extern BOOL transport_write_message(transport_ctx *, int);
059ec3d9
PH
588extern void tree_add_duplicate(uschar *, address_item *);
589extern void tree_add_nonrecipient(uschar *);
590extern void tree_add_unusable(host_item *);
b4f579d1 591extern void tree_dup(tree_node **, tree_node *);
059ec3d9 592extern int tree_insertnode(tree_node **, tree_node *);
55414b25 593extern tree_node *tree_search(tree_node *, const uschar *);
059ec3d9 594extern void tree_write(tree_node *, FILE *);
38a0a95f 595extern void tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *);
059ec3d9 596
8523533c
TK
597#ifdef WITH_CONTENT_SCAN
598extern void unspool_mbox(void);
599#endif
8c5d388a 600#ifdef SUPPORT_I18N
fc362fc5
JH
601extern void utf8_version_report(FILE *);
602#endif
8523533c 603
4deaf07d
PH
604extern int verify_address(address_item *, FILE *, int, int, int, int,
605 uschar *, uschar *, BOOL *);
379ba7d0 606extern int verify_check_dnsbl(int, const uschar **, uschar **);
4deaf07d 607extern int verify_check_header_address(uschar **, uschar **, int, int, int,
fe5b5d0b 608 uschar *, uschar *, int, int *);
059ec3d9 609extern int verify_check_headers(uschar **);
770747fd 610extern int verify_check_header_names_ascii(uschar **);
059ec3d9 611extern int verify_check_host(uschar **);
7c498df1 612extern int verify_check_notblind(BOOL);
3fb3231c 613extern int verify_check_given_host(const uschar **, const host_item *);
55414b25
JH
614extern int verify_check_this_host(const uschar **, unsigned int *,
615 const uschar*, const uschar *, const uschar **);
059ec3d9
PH
616extern address_item *verify_checked_sender(uschar *);
617extern void verify_get_ident(int);
618extern BOOL verify_sender(int *, uschar **);
619extern BOOL verify_sender_preliminary(int *, uschar **);
620extern void version_init(void);
621
42055a33 622extern BOOL write_chunk(transport_ctx *, uschar *, int);
17c76198
PP
623extern ssize_t write_to_fd_buf(int, const uschar *, size_t);
624
6940b3df 625
36eb5d3d
JH
626/******************************************************************************/
627/* Predicate: if an address is in a tainted pool.
628By extension, a variable pointing to this address is tainted.
629*/
630
631static inline BOOL
632is_tainted(const void * p)
633{
634#if defined(COMPILE_UTILITY) || defined(MACRO_PREDEF) || defined(EM_VERSION_C)
635return FALSE;
636
637#else
638extern BOOL is_tainted_fn(const void *);
4381d60b 639return is_tainted_fn(p);
36eb5d3d
JH
640#endif
641}
642
643/******************************************************************************/
644/* String functions */
645static inline uschar * __Ustrcat(uschar * dst, const uschar * src, const char * func, int line)
646{
647#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
648if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcat", CUS func, line);
649#endif
650return US strcat(CS dst, CCS src);
651}
652static inline uschar * __Ustrcpy(uschar * dst, const uschar * src, const char * func, int line)
653{
654#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
655if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcpy", CUS func, line);
656#endif
657return US strcpy(CS dst, CCS src);
658}
659static inline uschar * __Ustrncat(uschar * dst, const uschar * src, size_t n, const char * func, int line)
660{
661#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
662if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncat", CUS func, line);
663#endif
664return US strncat(CS dst, CCS src, n);
665}
666static inline uschar * __Ustrncpy(uschar * dst, const uschar * src, size_t n, const char * func, int line)
667{
668#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
669if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncpy", CUS func, line);
670#endif
671return US strncpy(CS dst, CCS src, n);
672}
673/*XXX will likely need unchecked copy also */
674
675
137ae145
JH
676/* Advance the string pointer given over any whitespace.
677Return the next char as there's enought places using it to be useful. */
678
679#define Uskip_whitespace(sp) skip_whitespace(CUSS sp)
680
681static inline uschar skip_whitespace(const uschar ** sp)
682{ while (isspace(**sp)) (*sp)++; return **sp; }
683
684
36eb5d3d
JH
685/******************************************************************************/
686
7172970e 687#if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
b66fecb4 688/* exim_chown - in some NFSv4 setups *seemes* to be an issue with
6940b3df 689chown(<exim-uid>, <exim-gid>).
b66fecb4 690
6940b3df
JH
691Probably because the idmapping is broken, misconfigured or set up in
692an unusal way. (see Bug 2931). As I'm not sure, if this was a single
693case of misconfiguration, or if there are more such broken systems
694out, I try to impose as least impact as possible and for now just write
695a panic log entry pointing to the bug report. You're encouraged to
696contact the developers, if you experience this issue.
b66fecb4 697
6940b3df
JH
698fd the file descriptor (or -1 if not valid)
699name the file name for error messages or for file operations,
700 if fd is < 0
701owner the owner
702group the group
b66fecb4 703
6940b3df 704returns 0 on success, -1 on failure */
b66fecb4 705
6940b3df 706static inline int
b66fecb4
HSHR
707exim_fchown(int fd, uid_t owner, gid_t group, const uschar *name)
708{
6940b3df
JH
709return fchown(fd, owner, group)
710 ? exim_chown_failure(fd, name, owner, group) : 0;
b66fecb4
HSHR
711}
712
6940b3df 713static inline int
b66fecb4
HSHR
714exim_chown(const uschar *name, uid_t owner, gid_t group)
715{
6940b3df
JH
716return chown(CCS name, owner, group)
717 ? exim_chown_failure(-1, name, owner, group) : 0;
b66fecb4 718}
e59797e3 719#endif /* !MACRO_PREDEF && !COMPILE_UTILITY */
36eb5d3d 720
e59797e3
JH
721/******************************************************************************/
722/* String functions */
723
f3ebb786 724#if !defined(MACRO_PREDEF)
e59797e3
JH
725/*************************************************
726* Copy and save string *
727*************************************************/
728
729/* This function assumes that memcpy() is faster than strcpy().
a76d120a 730The result is explicitly nul-terminated.
e59797e3
JH
731*/
732
e59797e3 733static inline uschar *
a76d120a
JH
734string_copyn_taint_trc(const uschar * s, unsigned len,
735 BOOL tainted, const char * func, int line)
e59797e3 736{
a76d120a 737uschar * ss = store_get_3(len + 1, tainted, func, line);
e59797e3 738memcpy(ss, s, len);
a76d120a 739ss[len] = '\0';
e59797e3
JH
740return ss;
741}
742
a76d120a
JH
743static inline uschar *
744string_copy_taint_trc(const uschar * s, BOOL tainted, const char * func, int line)
745{ return string_copyn_taint_trc(s, Ustrlen(s), tainted, func, line); }
f3ebb786 746
a76d120a
JH
747static inline uschar *
748string_copyn_trc(const uschar * s, unsigned len, const char * func, int line)
749{ return string_copyn_taint_trc(s, len, is_tainted(s), func, line); }
f3ebb786 750static inline uschar *
677481d4 751string_copy_trc(const uschar * s, const char * func, int line)
a76d120a
JH
752{ return string_copy_taint_trc(s, is_tainted(s), func, line); }
753
f3ebb786 754
a76d120a
JH
755/* String-copy functions explicitly setting the taint status */
756
757#define string_copyn_taint(s, len, tainted) \
758 string_copyn_taint_trc((s), (len), (tainted), __FUNCTION__, __LINE__)
759#define string_copy_taint(s, tainted) \
760 string_copy_taint_trc((s), (tainted), __FUNCTION__, __LINE__)
761
762/* Simple string-copy functions maintaining the taint */
763
764#define string_copyn(s, len) \
765 string_copyn_taint_trc((s), (len), is_tainted(s), __FUNCTION__, __LINE__)
677481d4 766#define string_copy(s) \
a76d120a 767 string_copy_taint_trc((s), is_tainted(s), __FUNCTION__, __LINE__)
677481d4 768
e59797e3
JH
769
770/*************************************************
771* Copy, lowercase and save string *
772*************************************************/
773
774/*
775Argument: string to copy
776Returns: copy of string in new store, with letters lowercased
777*/
778
779static inline uschar *
780string_copylc(const uschar *s)
781{
f3ebb786 782uschar *ss = store_get(Ustrlen(s) + 1, is_tainted(s));
e59797e3
JH
783uschar *p = ss;
784while (*s != 0) *p++ = tolower(*s++);
785*p = 0;
786return ss;
787}
788
789
790
e59797e3
JH
791/*************************************************
792* Copy, lowercase, and save string, given length *
793*************************************************/
794
795/* It is assumed the data contains no zeros. A zero is added
796onto the end.
797
798Arguments:
799 s string to copy
800 n number of characters
801
802Returns: copy of string in new store, with letters lowercased
803*/
804
805static inline uschar *
806string_copynlc(uschar *s, int n)
807{
f3ebb786 808uschar *ss = store_get(n + 1, is_tainted(s));
e59797e3
JH
809uschar *p = ss;
810while (n-- > 0) *p++ = tolower(*s++);
811*p = 0;
812return ss;
813}
814
815
1a44d9d7 816# ifndef COMPILE_UTILITY
f3ebb786
JH
817/*************************************************
818* Copy and save string in longterm store *
819*************************************************/
820
821/* This function assumes that memcpy() is faster than strcpy().
822
823Argument: string to copy
824Returns: copy of string in new store
825*/
826
827static inline uschar *
828string_copy_perm(const uschar *s, BOOL force_taint)
829{
830int old_pool = store_pool;
831int len = Ustrlen(s) + 1;
832uschar *ss;
833
834store_pool = POOL_PERM;
835ss = store_get(len, force_taint || is_tainted(s));
836memcpy(ss, s, len);
837store_pool = old_pool;
838return ss;
839}
1a44d9d7 840# endif
f3ebb786
JH
841
842
843
844/* sprintf into a buffer, taint-unchecked */
845
846static inline void
847string_format_nt(uschar * buf, int siz, const char * fmt, ...)
848{
849gstring gs = { .size = siz, .ptr = 0, .s = buf };
850va_list ap;
851va_start(ap, fmt);
852(void) string_vformat(&gs, SVFMT_TAINT_NOCHK, fmt, ap);
853va_end(ap);
854}
855
856
857
e59797e3
JH
858/******************************************************************************/
859/* Growable-string functions */
860
f3ebb786
JH
861/* Create a growable-string with some preassigned space */
862
863#define string_get_tainted(size, tainted) \
864 string_get_tainted_trc((size), (tainted), __FUNCTION__, __LINE__)
e59797e3
JH
865
866static inline gstring *
f3ebb786 867string_get_tainted_trc(unsigned size, BOOL tainted, const char * func, unsigned line)
e59797e3 868{
f3ebb786 869gstring * g = store_get_3(sizeof(gstring) + size, tainted, func, line);
e59797e3
JH
870g->size = size;
871g->ptr = 0;
872g->s = US(g + 1);
873return g;
874}
875
f3ebb786
JH
876#define string_get(size) \
877 string_get_trc((size), __FUNCTION__, __LINE__)
878
879static inline gstring *
880string_get_trc(unsigned size, const char * func, unsigned line)
881{
882return string_get_tainted_trc(size, FALSE, func, line);
883}
884
e59797e3
JH
885/* NUL-terminate the C string in the growable-string, and return it. */
886
887static inline uschar *
888string_from_gstring(gstring * g)
889{
890if (!g) return NULL;
891g->s[g->ptr] = '\0';
892return g->s;
893}
894
ba5120a4
JH
895static inline unsigned
896gstring_length(const gstring * g)
897{
898return g ? (unsigned)g->ptr : 0;
899}
900
f3ebb786
JH
901
902#define gstring_release_unused(g) \
903 gstring_release_unused_trc(g, __FUNCTION__, __LINE__)
904
e59797e3 905static inline void
f3ebb786 906gstring_release_unused_trc(gstring * g, const char * file, unsigned line)
e59797e3 907{
f3ebb786
JH
908if (g) store_release_above_3(g->s + (g->size = g->ptr + 1), file, line);
909}
910
911
912/* sprintf-append to a growable-string */
913
914#define string_fmt_append(g, fmt, ...) \
915 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
c4efe382 916 SVFMT_EXTEND|SVFMT_REBUFFER, fmt, __VA_ARGS__)
f3ebb786
JH
917
918#define string_fmt_append_f(g, flgs, fmt, ...) \
919 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
c4efe382 920 flgs, fmt, __VA_ARGS__)
f3ebb786
JH
921
922static inline gstring *
923string_fmt_append_f_trc(gstring * g, const uschar * func, unsigned line,
924 unsigned flags, const char *format, ...)
925{
926va_list ap;
927va_start(ap, format);
928g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
929 flags, format, ap);
930va_end(ap);
931return g;
e59797e3
JH
932}
933
e68def51
JH
934
935/* Copy the content of a string to tainted memory */
936
937static inline void
938gstring_rebuffer(gstring * g)
939{
940uschar * s = store_get(g->size, TRUE);
941memcpy(s, g->s, g->ptr);
942g->s = s;
943}
944
945
e59797e3 946/******************************************************************************/
8743d3ac
JH
947
948#define store_get_dns_answer() store_get_dns_answer_trc(CUS __FUNCTION__, __LINE__)
949
950static inline dns_answer *
951store_get_dns_answer_trc(const uschar * func, unsigned line)
952{
953return store_get_3(sizeof(dns_answer), TRUE, CCS func, line); /* use tainted mem */
954}
955
59a93276
JH
956/******************************************************************************/
957/* Routines with knowledge of spool layout */
958
959# ifndef COMPILE_UTILITY
960static inline void
961spool_pname_buf(uschar * buf, int len)
962{
963snprintf(CS buf, len, "%s/%s/input", spool_directory, queue_name);
964}
965
966static inline uschar *
967spool_dname(const uschar * purpose, uschar * subdir)
968{
969return string_sprintf("%s/%s/%s/%s",
970 spool_directory, queue_name, purpose, subdir);
971}
972# endif
973
974static inline uschar *
fc7bae7f 975spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir)
59a93276
JH
976{
977return string_sprintf("%s%s%s%s%s",
fc7bae7f 978 q, *q ? "/" : "",
59a93276
JH
979 purpose,
980 *subdir ? "/" : "", subdir);
981}
982
fc7bae7f
JH
983static inline uschar *
984spool_sname(const uschar * purpose, uschar * subdir)
985{
986return spool_q_sname(purpose, queue_name, subdir);
987}
988
989static inline uschar *
990spool_q_fname(const uschar * purpose, const uschar * q,
991 const uschar * subdir, const uschar * fname, const uschar * suffix)
992{
993return string_sprintf("%s/%s/%s/%s/%s%s",
994 spool_directory, q, purpose, subdir, fname, suffix);
995}
996
59a93276
JH
997static inline uschar *
998spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
8aa16eb7 999 const uschar * suffix)
59a93276 1000{
8aa16eb7
JH
1001#ifdef COMPILE_UTILITY /* version avoiding string-extension */
1002int len = Ustrlen(spool_directory) + 1 + Ustrlen(queue_name) + 1 + Ustrlen(purpose) + 1
1003 + Ustrlen(subdir) + 1 + Ustrlen(fname) + Ustrlen(suffix) + 1;
1004uschar * buf = store_get(len, FALSE);
1005string_format(buf, len, "%s/%s/%s/%s/%s%s",
1006 spool_directory, queue_name, purpose, subdir, fname, suffix);
1007return buf;
1008#else
fc7bae7f 1009return spool_q_fname(purpose, queue_name, subdir, fname, suffix);
8aa16eb7 1010#endif
59a93276
JH
1011}
1012
9b62f401 1013static inline void
59a93276
JH
1014set_subdir_str(uschar * subdir_str, const uschar * name,
1015 int search_sequence)
1016{
1017subdir_str[0] = split_spool_directory == (search_sequence == 0)
1018 ? name[5] : '\0';
1019subdir_str[1] = '\0';
1020}
1021
1022/******************************************************************************/
9e21ce8f
JH
1023/* Time calculations */
1024
9f01e50d 1025static inline void
a55697ac 1026timesince(struct timeval * diff, const struct timeval * then)
9f01e50d
JH
1027{
1028gettimeofday(diff, NULL);
1029diff->tv_sec -= then->tv_sec;
1030if ((diff->tv_usec -= then->tv_usec) < 0)
1031 {
1032 diff->tv_sec--;
1033 diff->tv_usec += 1000*1000;
1034 }
1035}
1036
1037static inline uschar *
a55697ac 1038string_timediff(const struct timeval * diff)
9f01e50d
JH
1039{
1040static uschar buf[sizeof("0.000s")];
1041
1042if (diff->tv_sec >= 5 || !LOGGING(millisec))
1043 return readconf_printtime((int)diff->tv_sec);
1044
b09c5f34 1045snprintf(CS buf, sizeof(buf), "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
9f01e50d
JH
1046return buf;
1047}
1048
1049
1050static inline uschar *
a55697ac 1051string_timesince(const struct timeval * then)
9f01e50d
JH
1052{
1053struct timeval diff;
1054timesince(&diff, then);
1055return string_timediff(&diff);
1056}
1057
1058static inline void
a55697ac 1059report_time_since(const struct timeval * t0, const uschar * where)
9f01e50d
JH
1060{
1061# ifdef MEASURE_TIMING
1062struct timeval diff;
1063timesince(&diff, t0);
1064fprintf(stderr, "%d %s:\t%ld.%06ld\n",
1065 (uint)getpid(), where, (long)diff.tv_sec, (long)diff.tv_usec);
1066# endif
1067}
1068
1069
1070static inline void
1071testharness_pause_ms(int millisec)
1072{
1073#ifndef MEASURE_TIMING
ff966302 1074if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec);
9f01e50d
JH
1075#endif
1076}
1077
9e21ce8f
JH
1078/******************************************************************************/
1079/* Taint-checked file opens */
1080
1081static inline int
1082exim_open2(const char *pathname, int flags)
1083{
1084if (!is_tainted(pathname)) return open(pathname, flags);
54a2a2a9 1085log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
9e21ce8f
JH
1086errno = EACCES;
1087return -1;
1088}
1089static inline int
1090exim_open(const char *pathname, int flags, mode_t mode)
1091{
1092if (!is_tainted(pathname)) return open(pathname, flags, mode);
54a2a2a9 1093log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
9e21ce8f
JH
1094errno = EACCES;
1095return -1;
1096}
1097static inline int
1098exim_openat(int dirfd, const char *pathname, int flags)
1099{
1100if (!is_tainted(pathname)) return openat(dirfd, pathname, flags);
54a2a2a9 1101log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
9e21ce8f
JH
1102errno = EACCES;
1103return -1;
1104}
1105static inline int
1106exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
1107{
1108if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode);
54a2a2a9 1109log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
9e21ce8f
JH
1110errno = EACCES;
1111return -1;
1112}
1113
1114static inline FILE *
1115exim_fopen(const char *pathname, const char *mode)
1116{
1117if (!is_tainted(pathname)) return fopen(pathname, mode);
54a2a2a9
JH
1118log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
1119errno = EACCES;
1120return NULL;
1121}
1122
1123static inline DIR *
1124exim_opendir(const uschar * name)
1125{
1126if (!is_tainted(name)) return opendir(CCS name);
1127log_write(0, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name);
9e21ce8f
JH
1128errno = EACCES;
1129return NULL;
1130}
1131
8e9fdd63 1132/******************************************************************************/
35c3c485 1133# if !defined(COMPILE_UTILITY)
8e9fdd63
JH
1134/* Process manipulation */
1135
1136static inline pid_t
1137exim_fork(const unsigned char * purpose)
1138{
56809214
JH
1139pid_t pid;
1140DEBUG(D_any) debug_printf("%s forking for %s\n", process_purpose, purpose);
1141if ((pid = fork()) == 0)
1142 {
1143 process_purpose = purpose;
1144 DEBUG(D_any) debug_printf("postfork: %s\n", purpose);
1145 }
1146else
1147 {
1148 testharness_pause_ms(100); /* let child work */
1149 DEBUG(D_any) debug_printf("%s forked for %s: %d\n", process_purpose, purpose, (int)pid);
1150 }
8e9fdd63
JH
1151return pid;
1152}
1153
56809214
JH
1154
1155static inline pid_t
1156child_open_exim(int * fdptr, const uschar * purpose)
1157{ return child_open_exim_function(fdptr, purpose); }
1158
1159static inline pid_t
1160child_open_exim2(int * fdptr, uschar * sender,
1161 uschar * sender_auth, const uschar * purpose)
1162{ return child_open_exim2_function(fdptr, sender, sender_auth, purpose); }
1163
eb24befc
JH
1164static inline pid_t
1165child_open(uschar **argv, uschar **envp, int newumask, int *infdptr,
1166 int *outfdptr, BOOL make_leader, const uschar * purpose)
1167{ return child_open_function(argv, envp, newumask, infdptr,
1168 outfdptr, make_leader, purpose);
1169}
1170
35c3c485 1171# endif /* !COMPILE_UTILITY */
8e9fdd63
JH
1172
1173/******************************************************************************/
eb2fb50d 1174#endif /* !MACRO_PREDEF */
b66fecb4
HSHR
1175
1176#endif /* _FUNCTIONS_H_ */
acec9514 1177
9d1c15ef
JH
1178/* vi: aw
1179*/
059ec3d9 1180/* End of functions.h */