X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/eb2fb50d46b0a27db9ccc32d3f4f32ece817402c..727a5d2511acd513514b52a72f8db294e54f3ae9:/src/src/functions.h diff --git a/src/src/functions.h b/src/src/functions.h index b902d2356..4a44096ea 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -22,7 +22,7 @@ extern uschar *init_perl(uschar *); #endif -#ifdef SUPPORT_TLS +#ifndef DISABLE_TLS extern const char * std_dh_prime_default(void); extern const char * @@ -51,14 +51,15 @@ extern BOOL tls_client_start(client_conn_ctx *, smtp_connect_args *, extern void tls_close(void *, int); extern BOOL tls_could_read(void); -extern int tls_export_cert(uschar *, size_t, void *); +extern void tls_daemon_init(void); +extern BOOL tls_export_cert(uschar *, size_t, void *); extern int tls_feof(void); extern int tls_ferror(void); extern void tls_free_cert(void **); extern int tls_getc(unsigned); extern uschar *tls_getbuf(unsigned *); extern void tls_get_cache(void); -extern int tls_import_cert(const uschar *, void **); +extern BOOL tls_import_cert(const uschar *, void **); extern int tls_read(void *, uschar *, size_t); extern int tls_server_start(const uschar *, uschar **); extern BOOL tls_smtp_buffered(void); @@ -66,7 +67,7 @@ extern int tls_ungetc(int); extern int tls_write(void *, const uschar *, size_t, BOOL); extern uschar *tls_validate_require_cipher(void); extern void tls_version_report(FILE *); -# ifndef USE_GNUTLS +# ifdef USE_OPENSSL extern BOOL tls_openssl_options_parse(uschar *, long *); # endif extern uschar * tls_field_from_dn(uschar *, const uschar *); @@ -76,7 +77,7 @@ extern BOOL tls_is_name_for_cert(const uschar *, void *); extern int tlsa_lookup(const host_item *, dns_answer *, BOOL); # endif -#endif /*SUPPORT_TLS*/ +#endif /*DISABLE_TLS*/ /* Everything else... */ @@ -185,7 +186,7 @@ extern void delivery_re_exec(int); extern BOOL directory_make(const uschar *, const uschar *, int, BOOL); #ifndef DISABLE_DKIM -extern uschar *dkim_exim_query_dns_txt(uschar *); +extern uschar *dkim_exim_query_dns_txt(const uschar *); extern void dkim_exim_sign_init(void); extern BOOL dkim_transport_write_message(transport_ctx *, @@ -194,6 +195,7 @@ extern BOOL dkim_transport_write_message(transport_ctx *, extern dns_address *dns_address_from_rr(dns_answer *, dns_record *); extern int dns_basic_lookup(dns_answer *, const uschar *, int); extern void dns_build_reverse(const uschar *, uschar *); +extern time_t dns_expire_from_soa(dns_answer *); extern void dns_init(BOOL, BOOL, BOOL); extern BOOL dns_is_aa(const dns_answer *); extern BOOL dns_is_secure(const dns_answer *); @@ -214,9 +216,10 @@ extern void msg_event_raise(const uschar *, const address_item *); extern int exim_chown_failure(int, const uschar*, uid_t, gid_t); extern const uschar * exim_errstr(int); -extern void exim_exit(int, const uschar *); +extern void exim_exit(int, const uschar *) NORETURN; extern void exim_nullstd(void); extern void exim_setugid(uid_t, gid_t, BOOL, uschar *); +extern void exim_underbar_exit(int); extern void exim_wait_tick(struct timeval *, int); extern int exp_bool(address_item *addr, uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue, @@ -230,7 +233,7 @@ extern uschar *expand_string_copy(const uschar *); extern int_eximarith_t expand_string_integer(uschar *, BOOL); extern void modify_variable(uschar *, void *); -extern BOOL fd_ready(int, int); +extern BOOL fd_ready(int, time_t); extern int filter_interpret(uschar *, int, address_item **, uschar **); extern BOOL filter_personal(string_item *, BOOL); @@ -239,8 +242,6 @@ extern BOOL filter_system_interpret(address_item **, uschar **); extern uschar * fn_hdrs_added(void); -extern void gstring_reset_unused(gstring *); - extern void header_add(int, const char *, ...); extern header_line *header_add_at_position_internal(BOOL, uschar *, BOOL, int, const char *, ...); extern int header_checkname(header_line *, BOOL); @@ -277,7 +278,7 @@ extern int ip_connectedsocket(int, const uschar *, int, int, int, host_item *, uschar **, const blob *); extern int ip_get_address_family(int); extern void ip_keepalive(int, const uschar *, BOOL); -extern int ip_recv(client_conn_ctx *, uschar *, int, int); +extern int ip_recv(client_conn_ctx *, uschar *, int, time_t); extern int ip_socket(int, int); extern int ip_tcpsocket(const uschar *, uschar **, int); @@ -349,7 +350,7 @@ extern uschar *parse_message_id(uschar *, uschar **, uschar **); extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL); extern uschar *parse_date_time(uschar *str, time_t *t); extern int vaguely_random_number(int); -#ifdef SUPPORT_TLS +#ifndef DISABLE_TLS extern int vaguely_random_number_fallback(int); #endif @@ -379,7 +380,7 @@ extern void readconf_rest(void); extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *); extern void readconf_save_config(const uschar *); extern void read_message_body(BOOL); -extern void receive_bomb_out(uschar *, uschar *); +extern void receive_bomb_out(uschar *, uschar *) NORETURN; extern BOOL receive_check_fs(int); extern BOOL receive_check_set_sender(uschar *); extern BOOL receive_msg(BOOL); @@ -437,10 +438,10 @@ extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *, extern void sigalrm_handler(int); extern BOOL smtp_buffered(void); extern void smtp_closedown(uschar *); -extern void smtp_command_timeout_exit(void); -extern void smtp_command_sigterm_exit(void); -extern void smtp_data_timeout_exit(void); -extern void smtp_data_sigint_exit(void); +extern void smtp_command_timeout_exit(void) NORETURN; +extern void smtp_command_sigterm_exit(void) NORETURN; +extern void smtp_data_timeout_exit(void) NORETURN; +extern void smtp_data_sigint_exit(void) NORETURN; extern uschar *smtp_cmd_hist(void); extern int smtp_connect(smtp_connect_args *, const blob *); extern int smtp_sock_connect(host_item *, int, int, uschar *, @@ -457,9 +458,9 @@ extern void smtp_get_cache(void); extern int smtp_handle_acl_fail(int, int, uschar *, uschar *); extern void smtp_log_no_mail(void); extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL); -extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int); +extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int) NORETURN; extern BOOL smtp_read_response(void *, uschar *, int, int, int); -extern void smtp_reset(void *); +extern void *smtp_reset(void *); extern void smtp_respond(uschar *, int, BOOL, uschar *); extern void smtp_notquit_exit(uschar *, uschar *, uschar *, ...); extern void smtp_port_for_connect(host_item *, int); @@ -474,18 +475,17 @@ extern int spam(const uschar **); extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **); #endif extern void spool_clear_header_globals(void); -extern uschar *spool_dname(const uschar *, uschar *); -extern uschar *spool_fname(const uschar *, const uschar *, const uschar *, const uschar *); extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *); extern int spool_open_datafile(uschar *); extern int spool_open_temp(uschar *); extern int spool_read_header(uschar *, BOOL, BOOL); -extern uschar *spool_sname(const uschar *, uschar *); extern int spool_write_header(uschar *, int, uschar **); extern int stdin_getc(unsigned); extern int stdin_feof(void); extern int stdin_ferror(void); extern int stdin_ungetc(int); + +extern void store_exit(void); extern gstring *string_append(gstring *, int, ...) WARN_UNUSED_RESULT; extern gstring *string_append_listele(gstring *, uschar, const uschar *) WARN_UNUSED_RESULT; extern gstring *string_append_listele_n(gstring *, uschar, const uschar *, unsigned) WARN_UNUSED_RESULT; @@ -496,21 +496,14 @@ extern gstring *string_catn(gstring *, const uschar *, int) WARN_UNUSED_RESULT; extern int string_compare_by_pointer(const void *, const void *); extern uschar *string_copy_dnsdomain(uschar *); extern uschar *string_copy_malloc(const uschar *); -extern uschar *string_copylc(const uschar *); -extern uschar *string_copynlc(uschar *, int); extern uschar *string_dequote(const uschar **); -extern gstring *string_fmt_append(gstring *, const char *, ...) ALMOST_PRINTF(2,3); -extern BOOL string_format(uschar *, int, const char *, ...) ALMOST_PRINTF(3,4); extern uschar *string_format_size(int, uschar *); -extern uschar *string_from_gstring(gstring *); -extern gstring *string_get(unsigned); extern int string_interpret_escape(const uschar **); extern int string_is_ip_address(const uschar *, int *); #ifdef SUPPORT_I18N extern BOOL string_is_utf8(const uschar *); #endif extern uschar *string_nextinlist(const uschar **, int *, uschar *, int); -extern uschar *string_open_failed(int, const char *, ...) PRINTF_FUNCTION(2,3); extern const uschar *string_printing2(const uschar *, BOOL); extern uschar *string_split_message(uschar *); extern uschar *string_timediff(struct timeval *); @@ -523,7 +516,23 @@ extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **); extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **); extern uschar *string_localpart_utf8_to_alabel(const uschar *, uschar **); #endif -extern gstring *string_vformat(gstring *, BOOL, const char *, va_list); + +#define string_format(buf, siz, fmt, ...) \ + string_format_trc(buf, siz, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__) +extern BOOL string_format_trc(uschar *, int, const uschar *, unsigned, + const char *, ...) ALMOST_PRINTF(5,6); + +#define string_vformat(g, flgs, fmt, ap) \ + string_vformat_trc(g, US __FUNCTION__, __LINE__, \ + STRING_SPRINTF_BUFFER_SIZE, flgs, fmt, ap) +extern gstring *string_vformat_trc(gstring *, const uschar *, unsigned, + unsigned, unsigned, const char *, va_list); + +#define string_open_failed(eno, fmt, ...) \ + string_open_failed_trc(eno, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__) +extern uschar *string_open_failed_trc(int, const uschar *, unsigned, + const char *, ...) PRINTF_FUNCTION(4,5); + extern int strcmpic(const uschar *, const uschar *); extern int strncmpic(const uschar *, const uschar *, int); extern uschar *strstric(uschar *, uschar *, BOOL); @@ -556,6 +565,7 @@ extern BOOL transport_write_message(transport_ctx *, int); extern void tree_add_duplicate(uschar *, address_item *); extern void tree_add_nonrecipient(uschar *); extern void tree_add_unusable(host_item *); +extern void tree_dup(tree_node **, tree_node *); extern int tree_insertnode(tree_node **, tree_node *); extern tree_node *tree_search(tree_node *, const uschar *); extern void tree_write(tree_node *, FILE *); @@ -590,7 +600,7 @@ extern BOOL write_chunk(transport_ctx *, uschar *, int); extern ssize_t write_to_fd_buf(int, const uschar *, size_t); -#ifndef MACRO_PREDEF +#if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY) /* exim_chown - in some NFSv4 setups *seemes* to be an issue with chown(, ). @@ -622,6 +632,276 @@ exim_chown(const uschar *name, uid_t owner, gid_t group) return chown(CCS name, owner, group) ? exim_chown_failure(-1, name, owner, group) : 0; } + +#endif /* !MACRO_PREDEF && !COMPILE_UTILITY */ +/******************************************************************************/ +/* String functions */ + +#if !defined(MACRO_PREDEF) +/************************************************* +* Copy and save string * +*************************************************/ + +/* This function assumes that memcpy() is faster than strcpy(). +*/ + +static inline uschar * +string_copy_taint_trc(const uschar *s, BOOL tainted, const char * func, int line) +{ +int len = Ustrlen(s) + 1; +uschar *ss = store_get_3(len, tainted, func, line); +memcpy(ss, s, len); +return ss; +} + +#define string_copy_taint(s, tainted) \ + string_copy_taint_trc((s), tainted, __FUNCTION__, __LINE__) + +static inline uschar * +string_copy(const uschar * s) +{ +return string_copy_taint((s), is_tainted(s)); +} + + +/************************************************* +* Copy, lowercase and save string * +*************************************************/ + +/* +Argument: string to copy +Returns: copy of string in new store, with letters lowercased +*/ + +static inline uschar * +string_copylc(const uschar *s) +{ +uschar *ss = store_get(Ustrlen(s) + 1, is_tainted(s)); +uschar *p = ss; +while (*s != 0) *p++ = tolower(*s++); +*p = 0; +return ss; +} + + + +/************************************************* +* Copy and save string, given length * +*************************************************/ + +/* It is assumed the data contains no zeros. A zero is added +onto the end. + +Arguments: + s string to copy + n number of characters + +Returns: copy of string in new store + +This is an API for local_scan hence not static. +*/ + +static inline uschar * +string_copyn(const uschar *s, int n) +{ +uschar *ss = store_get(n + 1, is_tainted(s)); +Ustrncpy(ss, s, n); +ss[n] = 0; +return ss; +} + +/************************************************* +* Copy, lowercase, and save string, given length * +*************************************************/ + +/* It is assumed the data contains no zeros. A zero is added +onto the end. + +Arguments: + s string to copy + n number of characters + +Returns: copy of string in new store, with letters lowercased +*/ + +static inline uschar * +string_copynlc(uschar *s, int n) +{ +uschar *ss = store_get(n + 1, is_tainted(s)); +uschar *p = ss; +while (n-- > 0) *p++ = tolower(*s++); +*p = 0; +return ss; +} + + +# ifndef COMPILE_UTILITY +/************************************************* +* Copy and save string in longterm store * +*************************************************/ + +/* This function assumes that memcpy() is faster than strcpy(). + +Argument: string to copy +Returns: copy of string in new store +*/ + +static inline uschar * +string_copy_perm(const uschar *s, BOOL force_taint) +{ +int old_pool = store_pool; +int len = Ustrlen(s) + 1; +uschar *ss; + +store_pool = POOL_PERM; +ss = store_get(len, force_taint || is_tainted(s)); +memcpy(ss, s, len); +store_pool = old_pool; +return ss; +} +# endif + + + +/* sprintf into a buffer, taint-unchecked */ + +static inline void +string_format_nt(uschar * buf, int siz, const char * fmt, ...) +{ +gstring gs = { .size = siz, .ptr = 0, .s = buf }; +va_list ap; +va_start(ap, fmt); +(void) string_vformat(&gs, SVFMT_TAINT_NOCHK, fmt, ap); +va_end(ap); +} + + + +/******************************************************************************/ +/* Growable-string functions */ + +/* Create a growable-string with some preassigned space */ + +#define string_get_tainted(size, tainted) \ + string_get_tainted_trc((size), (tainted), __FUNCTION__, __LINE__) + +static inline gstring * +string_get_tainted_trc(unsigned size, BOOL tainted, const char * func, unsigned line) +{ +gstring * g = store_get_3(sizeof(gstring) + size, tainted, func, line); +g->size = size; +g->ptr = 0; +g->s = US(g + 1); +return g; +} + +#define string_get(size) \ + string_get_trc((size), __FUNCTION__, __LINE__) + +static inline gstring * +string_get_trc(unsigned size, const char * func, unsigned line) +{ +return string_get_tainted_trc(size, FALSE, func, line); +} + +/* NUL-terminate the C string in the growable-string, and return it. */ + +static inline uschar * +string_from_gstring(gstring * g) +{ +if (!g) return NULL; +g->s[g->ptr] = '\0'; +return g->s; +} + + +#define gstring_release_unused(g) \ + gstring_release_unused_trc(g, __FUNCTION__, __LINE__) + +static inline void +gstring_release_unused_trc(gstring * g, const char * file, unsigned line) +{ +if (g) store_release_above_3(g->s + (g->size = g->ptr + 1), file, line); +} + + +/* sprintf-append to a growable-string */ + +#define string_fmt_append(g, fmt, ...) \ + string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \ + SVFMT_EXTEND|SVFMT_REBUFFER, fmt, __VA_ARGS__) + +#define string_fmt_append_f(g, flgs, fmt, ...) \ + string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \ + flgs, fmt, __VA_ARGS__) + +static inline gstring * +string_fmt_append_f_trc(gstring * g, const uschar * func, unsigned line, + unsigned flags, const char *format, ...) +{ +va_list ap; +va_start(ap, format); +g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE, + flags, format, ap); +va_end(ap); +return g; +} + +/******************************************************************************/ + +#define store_get_dns_answer() store_get_dns_answer_trc(CUS __FUNCTION__, __LINE__) + +static inline dns_answer * +store_get_dns_answer_trc(const uschar * func, unsigned line) +{ +return store_get_3(sizeof(dns_answer), TRUE, CCS func, line); /* use tainted mem */ +} + +/******************************************************************************/ +/* Routines with knowledge of spool layout */ + +# ifndef COMPILE_UTILITY +static inline void +spool_pname_buf(uschar * buf, int len) +{ +snprintf(CS buf, len, "%s/%s/input", spool_directory, queue_name); +} + +static inline uschar * +spool_dname(const uschar * purpose, uschar * subdir) +{ +return string_sprintf("%s/%s/%s/%s", + spool_directory, queue_name, purpose, subdir); +} +# endif + +static inline uschar * +spool_sname(const uschar * purpose, uschar * subdir) +{ +return string_sprintf("%s%s%s%s%s", + queue_name, *queue_name ? "/" : "", + purpose, + *subdir ? "/" : "", subdir); +} + +static inline uschar * +spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname, + const uschar * suffix) +{ +return string_sprintf("%s/%s/%s/%s/%s%s", + spool_directory, queue_name, purpose, subdir, fname, suffix); +} + +static void +set_subdir_str(uschar * subdir_str, const uschar * name, + int search_sequence) +{ +subdir_str[0] = split_spool_directory == (search_sequence == 0) + ? name[5] : '\0'; +subdir_str[1] = '\0'; +} + +/******************************************************************************/ #endif /* !MACRO_PREDEF */ #endif /* _FUNCTIONS_H_ */