Sqlite: new main option sqlite_dbfile
[exim.git] / src / src / functions.h
... / ...
CommitLineData
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
5/* Copyright (c) University of Cambridge 1995 - 2018 */
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. */
13#ifndef _FUNCTIONS_H_
14#define _FUNCTIONS_H_
15
16#include <sys/time.h>
17
18
19#ifdef EXIM_PERL
20extern gstring *call_perl_cat(gstring *, uschar **, uschar *,
21 uschar **) WARN_UNUSED_RESULT;
22extern void cleanup_perl(void);
23extern uschar *init_perl(uschar *);
24#endif
25
26
27#ifndef DISABLE_TLS
28extern const char *
29 std_dh_prime_default(void);
30extern const char *
31 std_dh_prime_named(const uschar *);
32
33extern uschar * tls_cert_crl_uri(void *, uschar * mod);
34extern uschar * tls_cert_ext_by_oid(void *, uschar *, int);
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);
45
46extern uschar * tls_cert_der_b64(void * cert);
47extern uschar * tls_cert_fprt_md5(void *);
48extern uschar * tls_cert_fprt_sha1(void *);
49extern uschar * tls_cert_fprt_sha256(void *);
50
51extern void tls_clean_env(void);
52extern BOOL tls_client_start(client_conn_ctx *, smtp_connect_args *,
53 void *, tls_support *, uschar **);
54
55extern void tls_close(void *, int);
56extern BOOL tls_could_read(void);
57extern void tls_daemon_init(void);
58extern BOOL tls_dropprivs_validate_require_cipher(BOOL);
59extern BOOL tls_export_cert(uschar *, size_t, void *);
60extern int tls_feof(void);
61extern int tls_ferror(void);
62extern void tls_free_cert(void **);
63extern int tls_getc(unsigned);
64extern uschar *tls_getbuf(unsigned *);
65extern void tls_get_cache(void);
66extern BOOL tls_import_cert(const uschar *, void **);
67extern int tls_read(void *, uschar *, size_t);
68extern int tls_server_start(const uschar *, uschar **);
69extern BOOL tls_smtp_buffered(void);
70extern int tls_ungetc(int);
71extern int tls_write(void *, const uschar *, size_t, BOOL);
72extern uschar *tls_validate_require_cipher(void);
73extern void tls_version_report(FILE *);
74# ifdef USE_OPENSSL
75extern BOOL tls_openssl_options_parse(uschar *, long *);
76# endif
77extern uschar * tls_field_from_dn(uschar *, const uschar *);
78extern BOOL tls_is_name_for_cert(const uschar *, void *);
79
80# ifdef SUPPORT_DANE
81extern int tlsa_lookup(const host_item *, dns_answer *, BOOL);
82# endif
83
84#endif /*DISABLE_TLS*/
85
86
87/* Everything else... */
88
89extern acl_block *acl_read(uschar *(*)(void), uschar **);
90extern int acl_check(int, uschar *, uschar *, uschar **, uschar **);
91extern int acl_eval(int, uschar *, uschar **, uschar **);
92
93extern tree_node *acl_var_create(uschar *);
94extern void acl_var_write(uschar *, uschar *, void *);
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 **);
100extern void arc_sign_init(void);
101extern const uschar *acl_verify_arc(void);
102extern uschar * fn_arc_domains(void);
103#endif
104
105extern void assert_no_variables(void *, int, const char *, int);
106extern int auth_call_pam(const uschar *, uschar **);
107extern int auth_call_pwcheck(uschar *, uschar **);
108extern int auth_call_radius(const uschar *, uschar **);
109extern int auth_call_saslauthd(const uschar *, const uschar *,
110 const uschar *, const uschar *, uschar **);
111extern int auth_check_serv_cond(auth_instance *);
112extern int auth_check_some_cond(auth_instance *, uschar *, uschar *, int);
113extern int auth_client_item(void *, auth_instance *, const uschar **,
114 unsigned, int, uschar *, int);
115
116
117extern int auth_get_data(uschar **, const uschar *, int);
118extern int auth_get_no64_data(uschar **, uschar *);
119extern int auth_prompt(const uschar *);
120extern int auth_read_input(const uschar *);
121extern void auth_show_supported(FILE *);
122extern uschar *auth_xtextencode(uschar *, int);
123extern int auth_xtextdecode(uschar *, uschar **);
124
125#ifdef EXPERIMENTAL_ARC
126extern gstring *authres_arc(gstring *);
127#endif
128#ifndef DISABLE_DKIM
129extern gstring *authres_dkim(gstring *);
130#endif
131#ifdef SUPPORT_DMARC
132extern gstring *authres_dmarc(gstring *);
133#endif
134extern gstring *authres_smtpauth(gstring *);
135#ifdef SUPPORT_SPF
136extern gstring *authres_spf(gstring *);
137#endif
138
139extern uschar *b64encode(const uschar *, int);
140extern uschar *b64encode_taint(const uschar *, int, BOOL);
141extern int b64decode(const uschar *, uschar **);
142extern int bdat_getc(unsigned);
143extern uschar *bdat_getbuf(unsigned *);
144extern int bdat_ungetc(int);
145extern void bdat_flush_data(void);
146
147extern void bits_clear(unsigned int *, size_t, int *);
148extern void bits_set(unsigned int *, size_t, int *);
149
150extern void cancel_cutthrough_connection(BOOL, const uschar *);
151extern int check_host(void *, const uschar *, const uschar **, uschar **);
152extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
153extern pid_t child_open_exim_function(int *, const uschar *);
154extern pid_t child_open_exim2_function(int *, uschar *, uschar *,
155 const uschar *);
156extern pid_t child_open_function(uschar **, uschar **, int,
157 int *, int *, BOOL, const uschar *);
158extern pid_t child_open_uid(const uschar **, const uschar **, int,
159 uid_t *, gid_t *, int *, int *, uschar *, BOOL, const uschar *);
160extern BOOL cleanup_environment(void);
161extern void cutthrough_data_puts(uschar *, int);
162extern void cutthrough_data_put_nl(void);
163extern uschar *cutthrough_finaldot(void);
164extern BOOL cutthrough_flush_send(void);
165extern BOOL cutthrough_headers_send(void);
166extern BOOL cutthrough_predata(void);
167extern void release_cutthrough_connection(const uschar *);
168
169extern void daemon_go(void);
170
171#ifdef EXPERIMENTAL_DCC
172extern int dcc_process(uschar **);
173#endif
174
175extern void debug_logging_activate(uschar *, uschar *);
176extern void debug_logging_stop(void);
177extern void debug_print_argv(const uschar **);
178extern void debug_print_ids(uschar *);
179extern void debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2);
180extern void debug_print_string(uschar *);
181extern void debug_print_tree(tree_node *);
182extern void debug_vprintf(int, const char *, va_list);
183extern void decode_bits(unsigned int *, size_t, int *,
184 uschar *, bit_table *, int, uschar *, int);
185extern void delete_pid_file(void);
186extern address_item *deliver_make_addr(uschar *, BOOL);
187extern void delivery_log(int, address_item *, int, uschar *);
188extern int deliver_message(uschar *, BOOL, BOOL);
189extern void deliver_msglog(const char *, ...) PRINTF_FUNCTION(1,2);
190extern void deliver_set_expansions(address_item *);
191extern int deliver_split_address(address_item *);
192extern void deliver_succeeded(address_item *);
193
194extern uschar *deliver_get_sender_address (uschar *id);
195extern void delivery_re_exec(int);
196
197extern void die_tainted(const uschar *, const uschar *, int);
198extern BOOL directory_make(const uschar *, const uschar *, int, BOOL);
199#ifndef DISABLE_DKIM
200extern uschar *dkim_exim_query_dns_txt(const uschar *);
201extern void dkim_exim_sign_init(void);
202
203extern BOOL dkim_transport_write_message(transport_ctx *,
204 struct ob_dkim *, const uschar ** errstr);
205#endif
206extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
207extern int dns_basic_lookup(dns_answer *, const uschar *, int);
208extern uschar *dns_build_reverse(const uschar *);
209extern time_t dns_expire_from_soa(dns_answer *, int);
210extern void dns_init(BOOL, BOOL, BOOL);
211extern BOOL dns_is_aa(const dns_answer *);
212extern BOOL dns_is_secure(const dns_answer *);
213extern int dns_lookup(dns_answer *, const uschar *, int, const uschar **);
214extern void dns_pattern_init(void);
215extern int dns_special_lookup(dns_answer *, const uschar *, int, const uschar **);
216extern dns_record *dns_next_rr(const dns_answer *, dns_scan *, int);
217extern uschar *dns_text_type(int);
218extern void dscp_list_to_stream(FILE *);
219extern BOOL dscp_lookup(const uschar *, int, int *, int *, int *);
220
221extern void enq_end(uschar *);
222extern BOOL enq_start(uschar *, unsigned);
223#ifndef DISABLE_EVENT
224extern uschar *event_raise(uschar *, const uschar *, uschar *);
225extern void msg_event_raise(const uschar *, const address_item *);
226#endif
227
228extern int exim_chown_failure(int, const uschar*, uid_t, gid_t);
229extern const uschar * exim_errstr(int);
230extern void exim_exit(int) NORETURN;
231extern void exim_nullstd(void);
232extern void exim_setugid(uid_t, gid_t, BOOL, uschar *);
233extern void exim_underbar_exit(int) NORETURN;
234extern void exim_wait_tick(struct timeval *, int);
235extern int exp_bool(address_item *addr,
236 uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue,
237 uschar *svalue, BOOL *rvalue);
238extern BOOL expand_check_condition(uschar *, uschar *, uschar *);
239extern uschar *expand_file_big_buffer(const uschar *);
240extern uschar *expand_string(uschar *); /* public, cannot make const */
241extern const uschar *expand_cstring(const uschar *); /* ... so use this one */
242extern uschar *expand_hide_passwords(uschar * );
243extern uschar *expand_string_copy(const uschar *);
244extern int_eximarith_t expand_string_integer(uschar *, BOOL);
245extern void modify_variable(uschar *, void *);
246
247extern BOOL fd_ready(int, time_t);
248
249extern int filter_interpret(uschar *, int, address_item **, uschar **);
250extern BOOL filter_personal(string_item *, BOOL);
251extern BOOL filter_runtest(int, uschar *, BOOL, BOOL);
252extern BOOL filter_system_interpret(address_item **, uschar **);
253
254extern uschar * fn_hdrs_added(void);
255
256extern void header_add(int, const char *, ...);
257extern header_line *header_add_at_position_internal(BOOL, uschar *, BOOL, int, const char *, ...);
258extern int header_checkname(header_line *, BOOL);
259extern BOOL header_match(uschar *, BOOL, BOOL, string_item *, int, ...);
260extern int host_address_extract_port(uschar *);
261extern uschar *host_and_ident(BOOL);
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 *);
265extern void host_build_log_info(void);
266extern void host_build_sender_fullhost(void);
267extern int host_find_byname(host_item *, const uschar *, int,
268 const uschar **, BOOL);
269extern int host_find_bydns(host_item *, const uschar *, int, uschar *, uschar *,
270 uschar *, const dnssec_domains *, const uschar **, BOOL *);
271extern ip_address_item *host_find_interfaces(void);
272extern BOOL host_is_in_net(const uschar *, const uschar *, int);
273extern BOOL host_is_tls_on_connect_port(int);
274extern int host_item_get_port(host_item *);
275extern void host_mask(int, int *, int);
276extern int host_name_lookup(void);
277extern int host_nmtoa(int, int *, int, uschar *, int);
278extern uschar *host_ntoa(int, const void *, uschar *, int *);
279extern int host_scan_for_local_hosts(host_item *, host_item **, BOOL *);
280
281extern uschar *imap_utf7_encode(uschar *, const uschar *,
282 uschar, uschar *, uschar **);
283
284extern void invert_address(uschar *, uschar *);
285extern int ip_addr(void *, int, const uschar *, int);
286extern int ip_bind(int, int, uschar *, int);
287extern int ip_connect(int, int, const uschar *, int, int, const blob *);
288extern int ip_connectedsocket(int, const uschar *, int, int,
289 int, host_item *, uschar **, const blob *);
290extern int ip_get_address_family(int);
291extern void ip_keepalive(int, const uschar *, BOOL);
292extern int ip_recv(client_conn_ctx *, uschar *, int, time_t);
293extern int ip_socket(int, int);
294
295extern int ip_tcpsocket(const uschar *, uschar **, int, host_item *);
296extern int ip_unixsocket(const uschar *, uschar **);
297extern int ip_streamsocket(const uschar *, uschar **, int, host_item *);
298
299extern int ipv6_nmtoa(int *, uschar *);
300
301extern uschar *local_part_quote(uschar *);
302extern int log_create(uschar *);
303extern int log_create_as_exim(uschar *);
304extern void log_close_all(void);
305
306extern macro_item * macro_create(const uschar *, const uschar *, BOOL);
307extern BOOL macro_read_assignment(uschar *);
308extern uschar *macros_expand(int, int *, BOOL *);
309extern void mainlog_close(void);
310#ifdef WITH_CONTENT_SCAN
311extern int malware(const uschar *, int);
312extern int malware_in_file(uschar *);
313extern void malware_init(void);
314extern void malware_show_supported(FILE *);
315#endif
316extern int match_address_list(const uschar *, BOOL, BOOL, const uschar **,
317 unsigned int *, int, int, const uschar **);
318extern int match_address_list_basic(const uschar *, const uschar **, int);
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 **);
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);
330#ifdef WITH_CONTENT_SCAN
331struct mime_boundary_context;
332extern int mime_acl_check(uschar *acl, FILE *f,
333 struct mime_boundary_context *, uschar **, uschar **);
334extern int mime_decode(const uschar **);
335extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *);
336extern int mime_regex(const uschar **);
337extern void mime_set_anomaly(int);
338#endif
339extern uschar *moan_check_errorcopy(uschar *);
340extern BOOL moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
341 BOOL, uschar *);
342extern void moan_smtp_batch(uschar *, const char *, ...) PRINTF_FUNCTION(2,3);
343extern BOOL moan_send_message(uschar *, int, error_block *eblock,
344 header_line *, FILE *, uschar *);
345extern void moan_tell_someone(uschar *, address_item *,
346 const uschar *, const char *, ...) PRINTF_FUNCTION(4,5);
347extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
348extern void moan_write_from(FILE *);
349extern void moan_write_references(FILE *, uschar *);
350extern FILE *modefopen(const uschar *, const char *, mode_t);
351
352extern int open_cutthrough_connection( address_item * addr );
353
354extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
355 BOOL);
356extern int parse_forward_list(uschar *, int, address_item **, uschar **,
357 const uschar *, uschar *, error_block **);
358extern uschar *parse_find_address_end(uschar *, BOOL);
359extern uschar *parse_find_at(uschar *);
360extern const uschar *parse_fix_phrase(const uschar *, int, uschar *, int);
361extern uschar *parse_message_id(uschar *, uschar **, uschar **);
362extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL);
363extern uschar *parse_date_time(uschar *str, time_t *t);
364extern int vaguely_random_number(int);
365#ifndef DISABLE_TLS
366extern int vaguely_random_number_fallback(int);
367#endif
368
369extern BOOL queue_action(uschar *, int, uschar **, int, int);
370extern void queue_check_only(void);
371extern unsigned queue_count(void);
372extern unsigned queue_count_cached(void);
373extern void queue_list(int, uschar **, int);
374#ifdef EXPERIMENTAL_QUEUE_RAMP
375extern void queue_notify_daemon(const uschar * hostname);
376#endif
377extern void queue_run(uschar *, uschar *, BOOL);
378
379extern int random_number(int);
380extern const uschar *rc_to_string(int);
381extern int rda_interpret(redirect_block *, int, uschar *, uschar *,
382 uschar *, uschar *, uschar *, ugid_block *, address_item **,
383 uschar **, error_block **, int *, uschar *);
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 *);
389extern void readconf_main(BOOL);
390extern void readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *);
391extern BOOL readconf_print(uschar *, uschar *, BOOL);
392extern uschar *readconf_printtime(int);
393extern uschar *readconf_readname(uschar *, int, uschar *);
394extern int readconf_readtime(const uschar *, int, BOOL);
395extern void readconf_rest(void);
396extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *);
397extern void readconf_save_config(const uschar *);
398extern void read_message_body(BOOL);
399extern void receive_bomb_out(uschar *, uschar *) NORETURN;
400extern BOOL receive_check_fs(int);
401extern BOOL receive_check_set_sender(uschar *);
402extern BOOL receive_msg(BOOL);
403extern int_eximarith_t receive_statvfs(BOOL, int *);
404extern void receive_swallow_smtp(void);
405#ifdef WITH_CONTENT_SCAN
406extern int regex(const uschar **);
407#endif
408extern BOOL regex_match_and_setup(const pcre *, const uschar *, int, int);
409extern const pcre *regex_must_compile(const uschar *, BOOL, BOOL);
410extern void retry_add_item(address_item *, uschar *, int);
411extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL,
412 uschar **, uschar **);
413extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
414extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *,
415 dbdata_retry *, time_t);
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);
419extern header_line *rewrite_header(header_line *,
420 const uschar *, const uschar *,
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);
429extern int route_check_prefix(const uschar *, const uschar *, unsigned *);
430extern int route_check_suffix(const uschar *, const uschar *, unsigned *);
431extern BOOL route_findgroup(uschar *, gid_t *);
432extern BOOL route_finduser(const uschar *, struct passwd **, uid_t *);
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);
438extern void route_show_supported(FILE *);
439extern void route_tidyup(void);
440
441extern uschar *search_find(void *, const uschar *, uschar *, int,
442 const uschar *, int, int, int *);
443extern int search_findtype(const uschar *, int);
444extern int search_findtype_partial(const uschar *, int *, const uschar **, int *,
445 int *);
446extern void *search_open(const uschar *, int, int, uid_t *, gid_t *);
447extern void search_tidyup(void);
448extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2);
449extern void sha1_end(hctx *, const uschar *, int, uschar *);
450extern void sha1_mid(hctx *, const uschar *);
451extern void sha1_start(hctx *);
452extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *,
453 uschar *, address_item **, uschar **);
454extern void sigalrm_handler(int);
455extern BOOL smtp_buffered(void);
456extern void smtp_closedown(uschar *);
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;
461extern void smtp_deliver_init(void);
462extern uschar *smtp_cmd_hist(void);
463extern int smtp_connect(smtp_connect_args *, const blob *);
464extern int smtp_sock_connect(host_item *, int, int, uschar *,
465 transport_instance * tb, int, const blob *);
466extern int smtp_feof(void);
467extern int smtp_ferror(void);
468extern uschar *smtp_get_connection_info(void);
469extern BOOL smtp_get_interface(uschar *, int, address_item *,
470 uschar **, uschar *);
471extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *);
472extern int smtp_getc(unsigned);
473extern uschar *smtp_getbuf(unsigned *);
474extern void smtp_get_cache(void);
475extern int smtp_handle_acl_fail(int, int, uschar *, uschar *);
476extern void smtp_log_no_mail(void);
477extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL);
478extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int) NORETURN;
479extern BOOL smtp_read_response(void *, uschar *, int, int, int);
480extern void *smtp_reset(void *);
481extern void smtp_respond(uschar *, int, BOOL, uschar *);
482extern void smtp_notquit_exit(uschar *, uschar *, uschar *, ...);
483extern void smtp_port_for_connect(host_item *, int);
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);
488extern BOOL smtp_verify_helo(void);
489extern int smtp_write_command(void *, int, const char *, ...) PRINTF_FUNCTION(3,4);
490#ifdef WITH_CONTENT_SCAN
491extern int spam(const uschar **);
492extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **);
493#endif
494extern void spool_clear_header_globals(void);
495extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *);
496extern int spool_open_datafile(uschar *);
497extern int spool_open_temp(uschar *);
498extern int spool_read_header(uschar *, BOOL, BOOL);
499extern int spool_write_header(uschar *, int, uschar **);
500extern int stdin_getc(unsigned);
501extern int stdin_feof(void);
502extern int stdin_ferror(void);
503extern int stdin_ungetc(int);
504
505extern void store_exit(void);
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;
509extern gstring *string_append2_listele_n(gstring *, const uschar *, const uschar *, unsigned) WARN_UNUSED_RESULT;
510extern uschar *string_base62(unsigned long int);
511extern gstring *string_cat (gstring *, const uschar * ) WARN_UNUSED_RESULT;
512extern gstring *string_catn(gstring *, const uschar *, int) WARN_UNUSED_RESULT;
513extern int string_compare_by_pointer(const void *, const void *);
514extern uschar *string_copy_dnsdomain(uschar *);
515extern uschar *string_copy_malloc(const uschar *);
516extern uschar *string_dequote(const uschar **);
517extern uschar *string_format_size(int, uschar *);
518extern int string_interpret_escape(const uschar **);
519extern int string_is_ip_address(const uschar *, int *);
520#ifdef SUPPORT_I18N
521extern BOOL string_is_utf8(const uschar *);
522#endif
523extern uschar *string_nextinlist(const uschar **, int *, uschar *, int);
524extern const uschar *string_printing2(const uschar *, BOOL);
525extern uschar *string_split_message(uschar *);
526extern uschar *string_unprinting(uschar *);
527#ifdef SUPPORT_I18N
528extern uschar *string_address_utf8_to_alabel(const uschar *, uschar **);
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
534
535#define string_format(buf, siz, fmt, ...) \
536 string_format_trc(buf, siz, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
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, ...) \
547 string_open_failed_trc(eno, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
548extern uschar *string_open_failed_trc(int, const uschar *, unsigned,
549 const char *, ...) PRINTF_FUNCTION(4,5);
550
551extern int strcmpic(const uschar *, const uschar *);
552extern int strncmpic(const uschar *, const uschar *, int);
553extern uschar *strstric(uschar *, uschar *, BOOL);
554
555extern int test_harness_fudged_queue_time(int);
556extern void tcp_init(void);
557#ifdef EXIM_TFO_PROBE
558extern void tfo_probe(void);
559#endif
560extern void tls_modify_variables(tls_support *);
561extern uschar *tod_stamp(int);
562
563extern BOOL transport_check_waiting(const uschar *, const uschar *, int, uschar *,
564 BOOL *, oicf, void*);
565extern void transport_init(void);
566extern void transport_do_pass_socket(const uschar *, const uschar *,
567 const uschar *, uschar *, int);
568extern BOOL transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *,
569 int);
570extern uschar *transport_rcpt_address(address_item *, BOOL);
571extern BOOL transport_set_up_command(const uschar ***, uschar *,
572 BOOL, int, address_item *, uschar *, uschar **);
573extern void transport_update_waiting(host_item *, uschar *);
574extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL);
575extern void transport_write_reset(int);
576extern BOOL transport_write_string(int, const char *, ...);
577extern BOOL transport_headers_send(transport_ctx *,
578 BOOL (*)(transport_ctx *, uschar *, int));
579extern void transport_show_supported(FILE *);
580extern BOOL transport_write_message(transport_ctx *, int);
581extern void tree_add_duplicate(uschar *, address_item *);
582extern void tree_add_nonrecipient(uschar *);
583extern void tree_add_unusable(host_item *);
584extern void tree_dup(tree_node **, tree_node *);
585extern int tree_insertnode(tree_node **, tree_node *);
586extern tree_node *tree_search(tree_node *, const uschar *);
587extern void tree_write(tree_node *, FILE *);
588extern void tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *);
589
590#ifdef WITH_CONTENT_SCAN
591extern void unspool_mbox(void);
592#endif
593#ifdef SUPPORT_I18N
594extern void utf8_version_report(FILE *);
595#endif
596
597extern int verify_address(address_item *, FILE *, int, int, int, int,
598 uschar *, uschar *, BOOL *);
599extern int verify_check_dnsbl(int, const uschar **, uschar **);
600extern int verify_check_header_address(uschar **, uschar **, int, int, int,
601 uschar *, uschar *, int, int *);
602extern int verify_check_headers(uschar **);
603extern int verify_check_header_names_ascii(uschar **);
604extern int verify_check_host(uschar **);
605extern int verify_check_notblind(BOOL);
606extern int verify_check_given_host(const uschar **, const host_item *);
607extern int verify_check_this_host(const uschar **, unsigned int *,
608 const uschar*, const uschar *, const uschar **);
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
615extern BOOL write_chunk(transport_ctx *, uschar *, int);
616extern ssize_t write_to_fd_buf(int, const uschar *, size_t);
617
618
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 *);
632return is_tainted_fn(p);
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
671#if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
672/* exim_chown - in some NFSv4 setups *seemes* to be an issue with
673chown(<exim-uid>, <exim-gid>).
674
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.
681
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
687
688returns 0 on success, -1 on failure */
689
690static inline int
691exim_fchown(int fd, uid_t owner, gid_t group, const uschar *name)
692{
693return fchown(fd, owner, group)
694 ? exim_chown_failure(fd, name, owner, group) : 0;
695}
696
697static inline int
698exim_chown(const uschar *name, uid_t owner, gid_t group)
699{
700return chown(CCS name, owner, group)
701 ? exim_chown_failure(-1, name, owner, group) : 0;
702}
703#endif /* !MACRO_PREDEF && !COMPILE_UTILITY */
704
705/******************************************************************************/
706/* String functions */
707
708#if !defined(MACRO_PREDEF)
709/*************************************************
710* Copy and save string *
711*************************************************/
712
713/* This function assumes that memcpy() is faster than strcpy().
714The result is explicitly nul-terminated.
715*/
716
717static inline uschar *
718string_copyn_taint_trc(const uschar * s, unsigned len,
719 BOOL tainted, const char * func, int line)
720{
721uschar * ss = store_get_3(len + 1, tainted, func, line);
722memcpy(ss, s, len);
723ss[len] = '\0';
724return ss;
725}
726
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); }
730
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); }
734static inline uschar *
735string_copy_trc(const uschar * s, const char * func, int line)
736{ return string_copy_taint_trc(s, is_tainted(s), func, line); }
737
738
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__)
750#define string_copy(s) \
751 string_copy_taint_trc((s), is_tainted(s), __FUNCTION__, __LINE__)
752
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{
766uschar *ss = store_get(Ustrlen(s) + 1, is_tainted(s));
767uschar *p = ss;
768while (*s != 0) *p++ = tolower(*s++);
769*p = 0;
770return ss;
771}
772
773
774
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{
792uschar *ss = store_get(n + 1, is_tainted(s));
793uschar *p = ss;
794while (n-- > 0) *p++ = tolower(*s++);
795*p = 0;
796return ss;
797}
798
799
800# ifndef COMPILE_UTILITY
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}
824# endif
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
842/******************************************************************************/
843/* Growable-string functions */
844
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__)
849
850static inline gstring *
851string_get_tainted_trc(unsigned size, BOOL tainted, const char * func, unsigned line)
852{
853gstring * g = store_get_3(sizeof(gstring) + size, tainted, func, line);
854g->size = size;
855g->ptr = 0;
856g->s = US(g + 1);
857return g;
858}
859
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
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
879static inline unsigned
880gstring_length(const gstring * g)
881{
882return g ? (unsigned)g->ptr : 0;
883}
884
885
886#define gstring_release_unused(g) \
887 gstring_release_unused_trc(g, __FUNCTION__, __LINE__)
888
889static inline void
890gstring_release_unused_trc(gstring * g, const char * file, unsigned line)
891{
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__, \
900 SVFMT_EXTEND|SVFMT_REBUFFER, fmt, __VA_ARGS__)
901
902#define string_fmt_append_f(g, flgs, fmt, ...) \
903 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
904 flgs, fmt, __VA_ARGS__)
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;
916}
917
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
930/******************************************************************************/
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
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 *
959spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir)
960{
961return string_sprintf("%s%s%s%s%s",
962 q, *q ? "/" : "",
963 purpose,
964 *subdir ? "/" : "", subdir);
965}
966
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
981static inline uschar *
982spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
983 const uschar * suffix)
984{
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
993return spool_q_fname(purpose, queue_name, subdir, fname, suffix);
994#endif
995}
996
997static inline void
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/******************************************************************************/
1007/* Time calculations */
1008
1009static inline void
1010timesince(struct timeval * diff, const struct timeval * then)
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 *
1022string_timediff(const struct timeval * diff)
1023{
1024static uschar buf[sizeof("0.000s")];
1025
1026if (diff->tv_sec >= 5 || !LOGGING(millisec))
1027 return readconf_printtime((int)diff->tv_sec);
1028
1029snprintf(CS buf, sizeof(buf), "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
1030return buf;
1031}
1032
1033
1034static inline uschar *
1035string_timesince(const struct timeval * then)
1036{
1037struct timeval diff;
1038timesince(&diff, then);
1039return string_timediff(&diff);
1040}
1041
1042static inline void
1043report_time_since(const struct timeval * t0, const uschar * where)
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
1058if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec);
1059#endif
1060}
1061
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);
1069log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
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);
1077log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
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);
1085log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
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);
1093log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
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);
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);
1112errno = EACCES;
1113return NULL;
1114}
1115
1116/******************************************************************************/
1117# if !defined(COMPILE_UTILITY)
1118/* Process manipulation */
1119
1120static inline pid_t
1121exim_fork(const unsigned char * purpose)
1122{
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 }
1135return pid;
1136}
1137
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
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
1155# endif /* !COMPILE_UTILITY */
1156
1157/******************************************************************************/
1158#endif /* !MACRO_PREDEF */
1159
1160#endif /* _FUNCTIONS_H_ */
1161
1162/* vi: aw
1163*/
1164/* End of functions.h */