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