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