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