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