Logging: Add DT= to defer & fail message lines. Bug 322
[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_uid(const uschar **, const uschar **, int,
154 uid_t *, gid_t *, int *, int *, uschar *, BOOL);
155extern BOOL cleanup_environment(void);
156extern void cutthrough_data_puts(uschar *, int);
157extern void cutthrough_data_put_nl(void);
158extern uschar *cutthrough_finaldot(void);
159extern BOOL cutthrough_flush_send(void);
160extern BOOL cutthrough_headers_send(void);
161extern BOOL cutthrough_predata(void);
162extern void release_cutthrough_connection(const uschar *);
163
164extern void daemon_go(void);
165
166#ifdef EXPERIMENTAL_DCC
167extern int dcc_process(uschar **);
168#endif
169
170extern void debug_logging_activate(uschar *, uschar *);
171extern void debug_logging_stop(void);
172extern void debug_print_argv(const uschar **);
173extern void debug_print_ids(uschar *);
174extern void debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2);
175extern void debug_print_string(uschar *);
176extern void debug_print_tree(tree_node *);
177extern void debug_vprintf(int, const char *, va_list);
178extern void decode_bits(unsigned int *, size_t, int *,
179 uschar *, bit_table *, int, uschar *, int);
180extern void delete_pid_file(void);
181extern address_item *deliver_make_addr(uschar *, BOOL);
182extern void delivery_log(int, address_item *, int, uschar *);
183extern int deliver_message(uschar *, BOOL, BOOL);
184extern void deliver_msglog(const char *, ...) PRINTF_FUNCTION(1,2);
185extern void deliver_set_expansions(address_item *);
186extern int deliver_split_address(address_item *);
187extern void deliver_succeeded(address_item *);
188
189extern uschar *deliver_get_sender_address (uschar *id);
190extern void delivery_re_exec(int);
191
192extern BOOL directory_make(const uschar *, const uschar *, int, BOOL);
193#ifndef DISABLE_DKIM
194extern uschar *dkim_exim_query_dns_txt(const uschar *);
195extern void dkim_exim_sign_init(void);
196
197extern BOOL dkim_transport_write_message(transport_ctx *,
198 struct ob_dkim *, const uschar ** errstr);
199#endif
200extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
201extern int dns_basic_lookup(dns_answer *, const uschar *, int);
202extern uschar *dns_build_reverse(const uschar *);
203extern time_t dns_expire_from_soa(dns_answer *, int);
204extern void dns_init(BOOL, BOOL, BOOL);
205extern BOOL dns_is_aa(const dns_answer *);
206extern BOOL dns_is_secure(const dns_answer *);
207extern int dns_lookup(dns_answer *, const uschar *, int, const uschar **);
208extern void dns_pattern_init(void);
209extern int dns_special_lookup(dns_answer *, const uschar *, int, const uschar **);
210extern dns_record *dns_next_rr(const dns_answer *, dns_scan *, int);
211extern uschar *dns_text_type(int);
212extern void dscp_list_to_stream(FILE *);
213extern BOOL dscp_lookup(const uschar *, int, int *, int *, int *);
214
215extern void enq_end(uschar *);
216extern BOOL enq_start(uschar *, unsigned);
217#ifndef DISABLE_EVENT
218extern uschar *event_raise(uschar *, const uschar *, uschar *);
219extern void msg_event_raise(const uschar *, const address_item *);
220#endif
221
222extern int exim_chown_failure(int, const uschar*, uid_t, gid_t);
223extern const uschar * exim_errstr(int);
224extern void exim_exit(int, const uschar *) NORETURN;
225extern void exim_nullstd(void);
226extern void exim_setugid(uid_t, gid_t, BOOL, uschar *);
227extern void exim_underbar_exit(int);
228extern void exim_wait_tick(struct timeval *, int);
229extern int exp_bool(address_item *addr,
230 uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue,
231 uschar *svalue, BOOL *rvalue);
232extern BOOL expand_check_condition(uschar *, uschar *, uschar *);
233extern uschar *expand_file_big_buffer(const uschar *);
234extern uschar *expand_string(uschar *); /* public, cannot make const */
235extern const uschar *expand_cstring(const uschar *); /* ... so use this one */
236extern uschar *expand_hide_passwords(uschar * );
237extern uschar *expand_string_copy(const uschar *);
238extern int_eximarith_t expand_string_integer(uschar *, BOOL);
239extern void modify_variable(uschar *, void *);
240
241extern BOOL fd_ready(int, time_t);
242
243extern int filter_interpret(uschar *, int, address_item **, uschar **);
244extern BOOL filter_personal(string_item *, BOOL);
245extern BOOL filter_runtest(int, uschar *, BOOL, BOOL);
246extern BOOL filter_system_interpret(address_item **, uschar **);
247
248extern uschar * fn_hdrs_added(void);
249
250extern void header_add(int, const char *, ...);
251extern header_line *header_add_at_position_internal(BOOL, uschar *, BOOL, int, const char *, ...);
252extern int header_checkname(header_line *, BOOL);
253extern BOOL header_match(uschar *, BOOL, BOOL, string_item *, int, ...);
254extern int host_address_extract_port(uschar *);
255extern uschar *host_and_ident(BOOL);
256extern int host_aton(const uschar *, int *);
257extern void host_build_hostlist(host_item **, const uschar *, BOOL);
258extern ip_address_item *host_build_ifacelist(const uschar *, uschar *);
259extern void host_build_log_info(void);
260extern void host_build_sender_fullhost(void);
261extern int host_find_byname(host_item *, const uschar *, int,
262 const uschar **, BOOL);
263extern int host_find_bydns(host_item *, const uschar *, int, uschar *, uschar *,
264 uschar *, const dnssec_domains *, const uschar **, BOOL *);
265extern ip_address_item *host_find_interfaces(void);
266extern BOOL host_is_in_net(const uschar *, const uschar *, int);
267extern BOOL host_is_tls_on_connect_port(int);
268extern int host_item_get_port(host_item *);
269extern void host_mask(int, int *, int);
270extern int host_name_lookup(void);
271extern int host_nmtoa(int, int *, int, uschar *, int);
272extern uschar *host_ntoa(int, const void *, uschar *, int *);
273extern int host_scan_for_local_hosts(host_item *, host_item **, BOOL *);
274
275extern uschar *imap_utf7_encode(uschar *, const uschar *,
276 uschar, uschar *, uschar **);
277
278extern void invert_address(uschar *, uschar *);
279extern int ip_addr(void *, int, const uschar *, int);
280extern int ip_bind(int, int, uschar *, int);
281extern int ip_connect(int, int, const uschar *, int, int, const blob *);
282extern int ip_connectedsocket(int, const uschar *, int, int,
283 int, host_item *, uschar **, const blob *);
284extern int ip_get_address_family(int);
285extern void ip_keepalive(int, const uschar *, BOOL);
286extern int ip_recv(client_conn_ctx *, uschar *, int, time_t);
287extern int ip_socket(int, int);
288
289extern int ip_tcpsocket(const uschar *, uschar **, int);
290extern int ip_unixsocket(const uschar *, uschar **);
291extern int ip_streamsocket(const uschar *, uschar **, int);
292
293extern int ipv6_nmtoa(int *, uschar *);
294
295extern uschar *local_part_quote(uschar *);
296extern int log_create(uschar *);
297extern int log_create_as_exim(uschar *);
298extern void log_close_all(void);
299
300extern macro_item * macro_create(const uschar *, const uschar *, BOOL);
301extern BOOL macro_read_assignment(uschar *);
302extern uschar *macros_expand(int, int *, BOOL *);
303extern void mainlog_close(void);
304#ifdef WITH_CONTENT_SCAN
305extern int malware(const uschar *, int);
306extern int malware_in_file(uschar *);
307extern void malware_init(void);
308extern void malware_show_supported(FILE *);
309#endif
310extern int match_address_list(const uschar *, BOOL, BOOL, const uschar **,
311 unsigned int *, int, int, const uschar **);
312extern int match_address_list_basic(const uschar *, const uschar **, int);
313extern int match_check_list(const uschar **, int, tree_node **, unsigned int **,
314 int(*)(void *, const uschar *, const uschar **, uschar **), void *, int,
315 const uschar *, const uschar **);
316extern int match_isinlist(const uschar *, const uschar **, int, tree_node **,
317 unsigned int *, int, BOOL, const uschar **);
318extern int match_check_string(const uschar *, const uschar *, int, BOOL, BOOL, BOOL,
319 const uschar **);
320extern void md5_end(md5 *, const uschar *, int, uschar *);
321extern void md5_mid(md5 *, const uschar *);
322extern void md5_start(md5 *);
323extern void millisleep(int);
324#ifdef WITH_CONTENT_SCAN
325struct mime_boundary_context;
326extern int mime_acl_check(uschar *acl, FILE *f,
327 struct mime_boundary_context *, uschar **, uschar **);
328extern int mime_decode(const uschar **);
329extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *);
330extern int mime_regex(const uschar **);
331extern void mime_set_anomaly(int);
332#endif
333extern uschar *moan_check_errorcopy(uschar *);
334extern BOOL moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
335 BOOL, uschar *);
336extern void moan_smtp_batch(uschar *, const char *, ...) PRINTF_FUNCTION(2,3);
337extern BOOL moan_send_message(uschar *, int, error_block *eblock,
338 header_line *, FILE *, uschar *);
339extern void moan_tell_someone(uschar *, address_item *,
340 const uschar *, const char *, ...) PRINTF_FUNCTION(4,5);
341extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
342extern void moan_write_from(FILE *);
343extern void moan_write_references(FILE *, uschar *);
344extern FILE *modefopen(const uschar *, const char *, mode_t);
345
346extern int open_cutthrough_connection( address_item * addr );
347
348extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
349 BOOL);
350extern int parse_forward_list(uschar *, int, address_item **, uschar **,
351 const uschar *, uschar *, error_block **);
352extern uschar *parse_find_address_end(uschar *, BOOL);
353extern uschar *parse_find_at(uschar *);
354extern const uschar *parse_fix_phrase(const uschar *, int, uschar *, int);
355extern uschar *parse_message_id(uschar *, uschar **, uschar **);
356extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL);
357extern uschar *parse_date_time(uschar *str, time_t *t);
358extern int vaguely_random_number(int);
359#ifndef DISABLE_TLS
360extern int vaguely_random_number_fallback(int);
361#endif
362
363extern BOOL queue_action(uschar *, int, uschar **, int, int);
364extern void queue_check_only(void);
365extern void queue_list(int, uschar **, int);
366extern void queue_count(void);
367extern void queue_run(uschar *, uschar *, BOOL);
368
369extern int random_number(int);
370extern const uschar *rc_to_string(int);
371extern int rda_interpret(redirect_block *, int, uschar *, uschar *,
372 uschar *, uschar *, uschar *, ugid_block *, address_item **,
373 uschar **, error_block **, int *, uschar *);
374extern int rda_is_filter(const uschar *);
375extern BOOL readconf_depends(driver_instance *, uschar *);
376extern void readconf_driver_init(uschar *, driver_instance **,
377 driver_info *, int, void *, int, optionlist *, int);
378extern uschar *readconf_find_option(void *);
379extern void readconf_main(BOOL);
380extern void readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *);
381extern BOOL readconf_print(uschar *, uschar *, BOOL);
382extern uschar *readconf_printtime(int);
383extern uschar *readconf_readname(uschar *, int, uschar *);
384extern int readconf_readtime(const uschar *, int, BOOL);
385extern void readconf_rest(void);
386extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *);
387extern void readconf_save_config(const uschar *);
388extern void read_message_body(BOOL);
389extern void receive_bomb_out(uschar *, uschar *) NORETURN;
390extern BOOL receive_check_fs(int);
391extern BOOL receive_check_set_sender(uschar *);
392extern BOOL receive_msg(BOOL);
393extern int_eximarith_t receive_statvfs(BOOL, int *);
394extern void receive_swallow_smtp(void);
395#ifdef WITH_CONTENT_SCAN
396extern int regex(const uschar **);
397#endif
398extern BOOL regex_match_and_setup(const pcre *, const uschar *, int, int);
399extern const pcre *regex_must_compile(const uschar *, BOOL, BOOL);
400extern void retry_add_item(address_item *, uschar *, int);
401extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL,
402 uschar **, uschar **);
403extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
404extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *,
405 dbdata_retry *, time_t);
406extern void retry_update(address_item **, address_item **, address_item **);
407extern uschar *rewrite_address(uschar *, BOOL, BOOL, rewrite_rule *, int);
408extern uschar *rewrite_address_qualify(uschar *, BOOL);
409extern header_line *rewrite_header(header_line *,
410 const uschar *, const uschar *,
411 rewrite_rule *, int, BOOL);
412extern uschar *rewrite_one(uschar *, int, BOOL *, BOOL, uschar *,
413 rewrite_rule *);
414extern void rewrite_test(uschar *);
415extern uschar *rfc2047_decode2(uschar *, BOOL, uschar *, int, int *, int *,
416 uschar **);
417extern int route_address(address_item *, address_item **, address_item **,
418 address_item **, address_item **, int);
419extern int route_check_prefix(const uschar *, const uschar *);
420extern int route_check_suffix(const uschar *, const uschar *);
421extern BOOL route_findgroup(uschar *, gid_t *);
422extern BOOL route_finduser(const uschar *, struct passwd **, uid_t *);
423extern BOOL route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
424 uschar **);
425extern BOOL route_find_expanded_user(uschar *, uschar *, uschar *,
426 struct passwd **, uid_t *, uschar **);
427extern void route_init(void);
428extern void route_show_supported(FILE *);
429extern void route_tidyup(void);
430
431extern uschar *search_find(void *, uschar *, uschar *, int, const uschar *, int,
432 int, int *);
433extern int search_findtype(const uschar *, int);
434extern int search_findtype_partial(const uschar *, int *, const uschar **, int *,
435 int *);
436extern void *search_open(uschar *, int, int, uid_t *, gid_t *);
437extern void search_tidyup(void);
438extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2);
439extern void sha1_end(hctx *, const uschar *, int, uschar *);
440extern void sha1_mid(hctx *, const uschar *);
441extern void sha1_start(hctx *);
442extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *,
443 uschar *, address_item **, uschar **);
444extern void sigalrm_handler(int);
445extern BOOL smtp_buffered(void);
446extern void smtp_closedown(uschar *);
447extern void smtp_command_timeout_exit(void) NORETURN;
448extern void smtp_command_sigterm_exit(void) NORETURN;
449extern void smtp_data_timeout_exit(void) NORETURN;
450extern void smtp_data_sigint_exit(void) NORETURN;
451extern void smtp_deliver_init(void);
452extern uschar *smtp_cmd_hist(void);
453extern int smtp_connect(smtp_connect_args *, const blob *);
454extern int smtp_sock_connect(host_item *, int, int, uschar *,
455 transport_instance * tb, int, const blob *);
456extern int smtp_feof(void);
457extern int smtp_ferror(void);
458extern uschar *smtp_get_connection_info(void);
459extern BOOL smtp_get_interface(uschar *, int, address_item *,
460 uschar **, uschar *);
461extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *);
462extern int smtp_getc(unsigned);
463extern uschar *smtp_getbuf(unsigned *);
464extern void smtp_get_cache(void);
465extern int smtp_handle_acl_fail(int, int, uschar *, uschar *);
466extern void smtp_log_no_mail(void);
467extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL);
468extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int) NORETURN;
469extern BOOL smtp_read_response(void *, uschar *, int, int, int);
470extern void *smtp_reset(void *);
471extern void smtp_respond(uschar *, int, BOOL, uschar *);
472extern void smtp_notquit_exit(uschar *, uschar *, uschar *, ...);
473extern void smtp_port_for_connect(host_item *, int);
474extern void smtp_send_prohibition_message(int, uschar *);
475extern int smtp_setup_msg(void);
476extern BOOL smtp_start_session(void);
477extern int smtp_ungetc(int);
478extern BOOL smtp_verify_helo(void);
479extern int smtp_write_command(void *, int, const char *, ...) PRINTF_FUNCTION(3,4);
480#ifdef WITH_CONTENT_SCAN
481extern int spam(const uschar **);
482extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **);
483#endif
484extern void spool_clear_header_globals(void);
485extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *);
486extern int spool_open_datafile(uschar *);
487extern int spool_open_temp(uschar *);
488extern int spool_read_header(uschar *, BOOL, BOOL);
489extern int spool_write_header(uschar *, int, uschar **);
490extern int stdin_getc(unsigned);
491extern int stdin_feof(void);
492extern int stdin_ferror(void);
493extern int stdin_ungetc(int);
494
495extern void store_exit(void);
496extern gstring *string_append(gstring *, int, ...) WARN_UNUSED_RESULT;
497extern gstring *string_append_listele(gstring *, uschar, const uschar *) WARN_UNUSED_RESULT;
498extern gstring *string_append_listele_n(gstring *, uschar, const uschar *, unsigned) WARN_UNUSED_RESULT;
499extern gstring *string_append2_listele_n(gstring *, const uschar *, const uschar *, unsigned) WARN_UNUSED_RESULT;
500extern uschar *string_base62(unsigned long int);
501extern gstring *string_cat (gstring *, const uschar * ) WARN_UNUSED_RESULT;
502extern gstring *string_catn(gstring *, const uschar *, int) WARN_UNUSED_RESULT;
503extern int string_compare_by_pointer(const void *, const void *);
504extern uschar *string_copy_dnsdomain(uschar *);
505extern uschar *string_copy_malloc(const uschar *);
506extern uschar *string_dequote(const uschar **);
507extern uschar *string_format_size(int, uschar *);
508extern int string_interpret_escape(const uschar **);
509extern int string_is_ip_address(const uschar *, int *);
510#ifdef SUPPORT_I18N
511extern BOOL string_is_utf8(const uschar *);
512#endif
513extern uschar *string_nextinlist(const uschar **, int *, uschar *, int);
514extern const uschar *string_printing2(const uschar *, BOOL);
515extern uschar *string_split_message(uschar *);
516extern uschar *string_unprinting(uschar *);
517#ifdef SUPPORT_I18N
518extern uschar *string_address_utf8_to_alabel(const uschar *, uschar **);
519extern uschar *string_domain_alabel_to_utf8(const uschar *, uschar **);
520extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **);
521extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **);
522extern uschar *string_localpart_utf8_to_alabel(const uschar *, uschar **);
523#endif
524
525#define string_format(buf, siz, fmt, ...) \
526 string_format_trc(buf, siz, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
527extern BOOL string_format_trc(uschar *, int, const uschar *, unsigned,
528 const char *, ...) ALMOST_PRINTF(5,6);
529
530#define string_vformat(g, flgs, fmt, ap) \
531 string_vformat_trc(g, US __FUNCTION__, __LINE__, \
532 STRING_SPRINTF_BUFFER_SIZE, flgs, fmt, ap)
533extern gstring *string_vformat_trc(gstring *, const uschar *, unsigned,
534 unsigned, unsigned, const char *, va_list);
535
536#define string_open_failed(eno, fmt, ...) \
537 string_open_failed_trc(eno, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
538extern uschar *string_open_failed_trc(int, const uschar *, unsigned,
539 const char *, ...) PRINTF_FUNCTION(4,5);
540
541extern int strcmpic(const uschar *, const uschar *);
542extern int strncmpic(const uschar *, const uschar *, int);
543extern uschar *strstric(uschar *, uschar *, BOOL);
544
545extern int test_harness_fudged_queue_time(int);
546extern void tcp_init(void);
547#ifdef EXIM_TFO_PROBE
548extern void tfo_probe(void);
549#endif
550extern void tls_modify_variables(tls_support *);
551extern uschar *tod_stamp(int);
552
553extern BOOL transport_check_waiting(const uschar *, const uschar *, int, uschar *,
554 BOOL *, oicf, void*);
555extern void transport_init(void);
556extern void transport_do_pass_socket(const uschar *, const uschar *,
557 const uschar *, uschar *, int);
558extern BOOL transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *,
559 int);
560extern uschar *transport_rcpt_address(address_item *, BOOL);
561extern BOOL transport_set_up_command(const uschar ***, uschar *,
562 BOOL, int, address_item *, uschar *, uschar **);
563extern void transport_update_waiting(host_item *, uschar *);
564extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL);
565extern void transport_write_reset(int);
566extern BOOL transport_write_string(int, const char *, ...);
567extern BOOL transport_headers_send(transport_ctx *,
568 BOOL (*)(transport_ctx *, uschar *, int));
569extern void transport_show_supported(FILE *);
570extern BOOL transport_write_message(transport_ctx *, int);
571extern void tree_add_duplicate(uschar *, address_item *);
572extern void tree_add_nonrecipient(uschar *);
573extern void tree_add_unusable(host_item *);
574extern void tree_dup(tree_node **, tree_node *);
575extern int tree_insertnode(tree_node **, tree_node *);
576extern tree_node *tree_search(tree_node *, const uschar *);
577extern void tree_write(tree_node *, FILE *);
578extern void tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *);
579
580#ifdef WITH_CONTENT_SCAN
581extern void unspool_mbox(void);
582#endif
583#ifdef SUPPORT_I18N
584extern void utf8_version_report(FILE *);
585#endif
586
587extern int verify_address(address_item *, FILE *, int, int, int, int,
588 uschar *, uschar *, BOOL *);
589extern int verify_check_dnsbl(int, const uschar **, uschar **);
590extern int verify_check_header_address(uschar **, uschar **, int, int, int,
591 uschar *, uschar *, int, int *);
592extern int verify_check_headers(uschar **);
593extern int verify_check_header_names_ascii(uschar **);
594extern int verify_check_host(uschar **);
595extern int verify_check_notblind(BOOL);
596extern int verify_check_given_host(const uschar **, const host_item *);
597extern int verify_check_this_host(const uschar **, unsigned int *,
598 const uschar*, const uschar *, const uschar **);
599extern address_item *verify_checked_sender(uschar *);
600extern void verify_get_ident(int);
601extern BOOL verify_sender(int *, uschar **);
602extern BOOL verify_sender_preliminary(int *, uschar **);
603extern void version_init(void);
604
605extern BOOL write_chunk(transport_ctx *, uschar *, int);
606extern ssize_t write_to_fd_buf(int, const uschar *, size_t);
607
608
609#if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
610/* exim_chown - in some NFSv4 setups *seemes* to be an issue with
611chown(<exim-uid>, <exim-gid>).
612
613Probably because the idmapping is broken, misconfigured or set up in
614an unusal way. (see Bug 2931). As I'm not sure, if this was a single
615case of misconfiguration, or if there are more such broken systems
616out, I try to impose as least impact as possible and for now just write
617a panic log entry pointing to the bug report. You're encouraged to
618contact the developers, if you experience this issue.
619
620fd the file descriptor (or -1 if not valid)
621name the file name for error messages or for file operations,
622 if fd is < 0
623owner the owner
624group the group
625
626returns 0 on success, -1 on failure */
627
628static inline int
629exim_fchown(int fd, uid_t owner, gid_t group, const uschar *name)
630{
631return fchown(fd, owner, group)
632 ? exim_chown_failure(fd, name, owner, group) : 0;
633}
634
635static inline int
636exim_chown(const uschar *name, uid_t owner, gid_t group)
637{
638return chown(CCS name, owner, group)
639 ? exim_chown_failure(-1, name, owner, group) : 0;
640}
641
642#endif /* !MACRO_PREDEF && !COMPILE_UTILITY */
643/******************************************************************************/
644/* String functions */
645
646#if !defined(MACRO_PREDEF)
647/*************************************************
648* Copy and save string *
649*************************************************/
650
651/* This function assumes that memcpy() is faster than strcpy().
652*/
653
654static inline uschar *
655string_copy_taint_trc(const uschar *s, BOOL tainted, const char * func, int line)
656{
657int len = Ustrlen(s) + 1;
658uschar *ss = store_get_3(len, tainted, func, line);
659memcpy(ss, s, len);
660return ss;
661}
662
663#define string_copy_taint(s, tainted) \
664 string_copy_taint_trc((s), tainted, __FUNCTION__, __LINE__)
665
666static inline uschar *
667string_copy(const uschar * s)
668{
669return string_copy_taint((s), is_tainted(s));
670}
671
672
673/*************************************************
674* Copy, lowercase and save string *
675*************************************************/
676
677/*
678Argument: string to copy
679Returns: copy of string in new store, with letters lowercased
680*/
681
682static inline uschar *
683string_copylc(const uschar *s)
684{
685uschar *ss = store_get(Ustrlen(s) + 1, is_tainted(s));
686uschar *p = ss;
687while (*s != 0) *p++ = tolower(*s++);
688*p = 0;
689return ss;
690}
691
692
693
694/*************************************************
695* Copy and save string, given length *
696*************************************************/
697
698/* It is assumed the data contains no zeros. A zero is added
699onto the end.
700
701Arguments:
702 s string to copy
703 n number of characters
704
705Returns: copy of string in new store
706
707This is an API for local_scan hence not static.
708*/
709
710static inline uschar *
711string_copyn(const uschar *s, int n)
712{
713uschar *ss = store_get(n + 1, is_tainted(s));
714Ustrncpy(ss, s, n);
715ss[n] = 0;
716return ss;
717}
718
719/*************************************************
720* Copy, lowercase, and save string, given length *
721*************************************************/
722
723/* It is assumed the data contains no zeros. A zero is added
724onto the end.
725
726Arguments:
727 s string to copy
728 n number of characters
729
730Returns: copy of string in new store, with letters lowercased
731*/
732
733static inline uschar *
734string_copynlc(uschar *s, int n)
735{
736uschar *ss = store_get(n + 1, is_tainted(s));
737uschar *p = ss;
738while (n-- > 0) *p++ = tolower(*s++);
739*p = 0;
740return ss;
741}
742
743
744# ifndef COMPILE_UTILITY
745/*************************************************
746* Copy and save string in longterm store *
747*************************************************/
748
749/* This function assumes that memcpy() is faster than strcpy().
750
751Argument: string to copy
752Returns: copy of string in new store
753*/
754
755static inline uschar *
756string_copy_perm(const uschar *s, BOOL force_taint)
757{
758int old_pool = store_pool;
759int len = Ustrlen(s) + 1;
760uschar *ss;
761
762store_pool = POOL_PERM;
763ss = store_get(len, force_taint || is_tainted(s));
764memcpy(ss, s, len);
765store_pool = old_pool;
766return ss;
767}
768# endif
769
770
771
772/* sprintf into a buffer, taint-unchecked */
773
774static inline void
775string_format_nt(uschar * buf, int siz, const char * fmt, ...)
776{
777gstring gs = { .size = siz, .ptr = 0, .s = buf };
778va_list ap;
779va_start(ap, fmt);
780(void) string_vformat(&gs, SVFMT_TAINT_NOCHK, fmt, ap);
781va_end(ap);
782}
783
784
785
786/******************************************************************************/
787/* Growable-string functions */
788
789/* Create a growable-string with some preassigned space */
790
791#define string_get_tainted(size, tainted) \
792 string_get_tainted_trc((size), (tainted), __FUNCTION__, __LINE__)
793
794static inline gstring *
795string_get_tainted_trc(unsigned size, BOOL tainted, const char * func, unsigned line)
796{
797gstring * g = store_get_3(sizeof(gstring) + size, tainted, func, line);
798g->size = size;
799g->ptr = 0;
800g->s = US(g + 1);
801return g;
802}
803
804#define string_get(size) \
805 string_get_trc((size), __FUNCTION__, __LINE__)
806
807static inline gstring *
808string_get_trc(unsigned size, const char * func, unsigned line)
809{
810return string_get_tainted_trc(size, FALSE, func, line);
811}
812
813/* NUL-terminate the C string in the growable-string, and return it. */
814
815static inline uschar *
816string_from_gstring(gstring * g)
817{
818if (!g) return NULL;
819g->s[g->ptr] = '\0';
820return g->s;
821}
822
823
824#define gstring_release_unused(g) \
825 gstring_release_unused_trc(g, __FUNCTION__, __LINE__)
826
827static inline void
828gstring_release_unused_trc(gstring * g, const char * file, unsigned line)
829{
830if (g) store_release_above_3(g->s + (g->size = g->ptr + 1), file, line);
831}
832
833
834/* sprintf-append to a growable-string */
835
836#define string_fmt_append(g, fmt, ...) \
837 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
838 SVFMT_EXTEND|SVFMT_REBUFFER, fmt, __VA_ARGS__)
839
840#define string_fmt_append_f(g, flgs, fmt, ...) \
841 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
842 flgs, fmt, __VA_ARGS__)
843
844static inline gstring *
845string_fmt_append_f_trc(gstring * g, const uschar * func, unsigned line,
846 unsigned flags, const char *format, ...)
847{
848va_list ap;
849va_start(ap, format);
850g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
851 flags, format, ap);
852va_end(ap);
853return g;
854}
855
856/******************************************************************************/
857
858#define store_get_dns_answer() store_get_dns_answer_trc(CUS __FUNCTION__, __LINE__)
859
860static inline dns_answer *
861store_get_dns_answer_trc(const uschar * func, unsigned line)
862{
863return store_get_3(sizeof(dns_answer), TRUE, CCS func, line); /* use tainted mem */
864}
865
866/******************************************************************************/
867/* Routines with knowledge of spool layout */
868
869# ifndef COMPILE_UTILITY
870static inline void
871spool_pname_buf(uschar * buf, int len)
872{
873snprintf(CS buf, len, "%s/%s/input", spool_directory, queue_name);
874}
875
876static inline uschar *
877spool_dname(const uschar * purpose, uschar * subdir)
878{
879return string_sprintf("%s/%s/%s/%s",
880 spool_directory, queue_name, purpose, subdir);
881}
882# endif
883
884static inline uschar *
885spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir)
886{
887return string_sprintf("%s%s%s%s%s",
888 q, *q ? "/" : "",
889 purpose,
890 *subdir ? "/" : "", subdir);
891}
892
893static inline uschar *
894spool_sname(const uschar * purpose, uschar * subdir)
895{
896return spool_q_sname(purpose, queue_name, subdir);
897}
898
899static inline uschar *
900spool_q_fname(const uschar * purpose, const uschar * q,
901 const uschar * subdir, const uschar * fname, const uschar * suffix)
902{
903return string_sprintf("%s/%s/%s/%s/%s%s",
904 spool_directory, q, purpose, subdir, fname, suffix);
905}
906
907static inline uschar *
908spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
909 const uschar * suffix)
910{
911#ifdef COMPILE_UTILITY /* version avoiding string-extension */
912int len = Ustrlen(spool_directory) + 1 + Ustrlen(queue_name) + 1 + Ustrlen(purpose) + 1
913 + Ustrlen(subdir) + 1 + Ustrlen(fname) + Ustrlen(suffix) + 1;
914uschar * buf = store_get(len, FALSE);
915string_format(buf, len, "%s/%s/%s/%s/%s%s",
916 spool_directory, queue_name, purpose, subdir, fname, suffix);
917return buf;
918#else
919return spool_q_fname(purpose, queue_name, subdir, fname, suffix);
920#endif
921}
922
923static inline void
924set_subdir_str(uschar * subdir_str, const uschar * name,
925 int search_sequence)
926{
927subdir_str[0] = split_spool_directory == (search_sequence == 0)
928 ? name[5] : '\0';
929subdir_str[1] = '\0';
930}
931
932/******************************************************************************/
933static inline void
934timesince(struct timeval * diff, const struct timeval * then)
935{
936gettimeofday(diff, NULL);
937diff->tv_sec -= then->tv_sec;
938if ((diff->tv_usec -= then->tv_usec) < 0)
939 {
940 diff->tv_sec--;
941 diff->tv_usec += 1000*1000;
942 }
943}
944
945static inline uschar *
946string_timediff(const struct timeval * diff)
947{
948static uschar buf[sizeof("0.000s")];
949
950if (diff->tv_sec >= 5 || !LOGGING(millisec))
951 return readconf_printtime((int)diff->tv_sec);
952
953snprintf(CS buf, sizeof(buf), "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
954return buf;
955}
956
957
958static inline uschar *
959string_timesince(const struct timeval * then)
960{
961struct timeval diff;
962timesince(&diff, then);
963return string_timediff(&diff);
964}
965
966static inline void
967report_time_since(const struct timeval * t0, const uschar * where)
968{
969# ifdef MEASURE_TIMING
970struct timeval diff;
971timesince(&diff, t0);
972fprintf(stderr, "%d %s:\t%ld.%06ld\n",
973 (uint)getpid(), where, (long)diff.tv_sec, (long)diff.tv_usec);
974# endif
975}
976
977
978static inline void
979testharness_pause_ms(int millisec)
980{
981#ifndef MEASURE_TIMING
982if (f.running_in_test_harness) millisleep(millisec);
983#endif
984}
985
986#endif /* !MACRO_PREDEF */
987
988#endif /* _FUNCTIONS_H_ */
989
990/* vi: aw
991*/
992/* End of functions.h */