X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/f4ee74acd38ba15c920cf59af1a3ade933c7e14f..01a4a5c5cbaa40ca618d3e233991ce183b551477:/src/src/exim.c diff --git a/src/src/exim.c b/src/src/exim.c index f50cc0814..e0b754666 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2012 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -12,6 +12,13 @@ Also a few functions that don't naturally fit elsewhere. */ #include "exim.h" +#ifdef USE_GNUTLS +# include +# if GNUTLS_VERSION_NUMBER < 0x030103 && !defined(DISABLE_OCSP) +# define DISABLE_OCSP +# endif +#endif + extern void init_lookup_list(void); @@ -124,10 +131,11 @@ Returns: TRUE or FALSE */ BOOL -regex_match_and_setup(const pcre *re, uschar *subject, int options, int setup) +regex_match_and_setup(const pcre *re, const uschar *subject, int options, int setup) { int ovector[3*(EXPAND_MAXN+1)]; -int n = pcre_exec(re, NULL, CS subject, Ustrlen(subject), 0, +uschar * s = string_copy(subject); /* de-constifying */ +int n = pcre_exec(re, NULL, CS s, Ustrlen(s), 0, PCRE_EOPT | options, ovector, sizeof(ovector)/sizeof(int)); BOOL yield = n >= 0; if (n == 0) n = EXPAND_MAXN + 1; @@ -137,7 +145,7 @@ if (yield) expand_nmax = (setup < 0)? 0 : setup + 1; for (nn = (setup < 0)? 0 : 2; nn < n*2; nn += 2) { - expand_nstring[expand_nmax] = subject + ovector[nn]; + expand_nstring[expand_nmax] = s + ovector[nn]; expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn]; } expand_nmax--; @@ -222,7 +230,7 @@ to disrupt whatever is going on outside the signal handler. */ if (fd < 0) return; -(void)write(fd, process_info, process_info_len); +{int dummy = write(fd, process_info, process_info_len); dummy = dummy; } (void)close(fd); } @@ -267,6 +275,10 @@ will wait for ever, so we panic in this instance. (There was a case of this when a bug in a function that calls milliwait() caused it to pass invalid data. That's when I added the check. :-) +We assume it to be not worth sleeping for under 100us; this value will +require revisiting as hardware advances. This avoids the issue of +a zero-valued timer setting meaning "never fire". + Argument: an itimerval structure containing the interval Returns: nothing */ @@ -276,6 +288,9 @@ milliwait(struct itimerval *itval) { sigset_t sigmask; sigset_t old_sigmask; + +if (itval->it_value.tv_usec < 100 && itval->it_value.tv_sec == 0) + return; (void)sigemptyset(&sigmask); /* Empty mask */ (void)sigaddset(&sigmask, SIGALRM); /* Add SIGALRM */ (void)sigprocmask(SIG_BLOCK, &sigmask, &old_sigmask); /* Block SIGALRM */ @@ -398,10 +413,11 @@ if (exim_tvcmp(&now_tv, then_tv) <= 0) { if (!running_in_test_harness) { - debug_printf("tick check: %lu.%06lu %lu.%06lu\n", - then_tv->tv_sec, then_tv->tv_usec, now_tv.tv_sec, now_tv.tv_usec); - debug_printf("waiting %lu.%06lu\n", itval.it_value.tv_sec, - itval.it_value.tv_usec); + debug_printf("tick check: " TIME_T_FMT ".%06lu " TIME_T_FMT ".%06lu\n", + then_tv->tv_sec, (long) then_tv->tv_usec, + now_tv.tv_sec, (long) now_tv.tv_usec); + debug_printf("waiting " TIME_T_FMT ".%06lu\n", + itval.it_value.tv_sec, (long) itval.it_value.tv_usec); } } @@ -526,7 +542,7 @@ close_unwanted(void) if (smtp_input) { #ifdef SUPPORT_TLS - tls_close(FALSE); /* Shut down the TLS library */ + tls_close(TRUE, FALSE); /* Shut down the TLS library */ #endif (void)close(fileno(smtp_in)); (void)close(fileno(smtp_out)); @@ -804,6 +820,12 @@ fprintf(f, "Support for:"); #ifdef WITH_OLD_DEMIME fprintf(f, " Old_Demime"); #endif +#ifndef DISABLE_PRDR + fprintf(f, " PRDR"); +#endif +#ifndef DISABLE_OCSP + fprintf(f, " OCSP"); +#endif #ifdef EXPERIMENTAL_SPF fprintf(f, " Experimental_SPF"); #endif @@ -813,9 +835,27 @@ fprintf(f, "Support for:"); #ifdef EXPERIMENTAL_BRIGHTMAIL fprintf(f, " Experimental_Brightmail"); #endif +#ifdef EXPERIMENTAL_DANE + fprintf(f, " Experimental_DANE"); +#endif #ifdef EXPERIMENTAL_DCC fprintf(f, " Experimental_DCC"); #endif +#ifdef EXPERIMENTAL_DMARC + fprintf(f, " Experimental_DMARC"); +#endif +#ifdef EXPERIMENTAL_PROXY + fprintf(f, " Experimental_Proxy"); +#endif +#ifdef EXPERIMENTAL_EVENT + fprintf(f, " Experimental_Event"); +#endif +#ifdef EXPERIMENTAL_REDIS + fprintf(f, " Experimental_Redis"); +#endif +#ifdef EXPERIMENTAL_DSN + fprintf(f, " Experimental_DSN"); +#endif fprintf(f, "\n"); fprintf(f, "Lookups (built-in):"); @@ -2638,6 +2678,16 @@ for (i = 1; i < argc; i++) break; } + #ifdef EXPERIMENTAL_DSN + /* -MCD: set the smtp_use_dsn flag; this indicates that the host + that exim is connected to supports the esmtp extension DSN */ + else if (Ustrcmp(argrest, "CD") == 0) + { + smtp_use_dsn = TRUE; + break; + } + #endif + /* -MCP: set the smtp_use_pipelining flag; this is useful only when it preceded -MC (see above) */ @@ -2971,6 +3021,23 @@ for (i = 1; i < argc; i++) else if (Ustrcmp(argrest, "Mi") == 0) interface_address = argv[++i]; + /* -oMm: Message reference */ + + else if (Ustrcmp(argrest, "Mm") == 0) + { + if (!mac_ismsgid(argv[i+1])) + { + fprintf(stderr,"-oMm must be a valid message ID\n"); + exit(EXIT_FAILURE); + } + if (!trusted_config) + { + fprintf(stderr,"-oMm must be called by a trusted user/config\n"); + exit(EXIT_FAILURE); + } + message_reference = argv[++i]; + } + /* -oMr: Received protocol */ else if (Ustrcmp(argrest, "Mr") == 0) received_protocol = argv[++i]; @@ -3276,7 +3343,7 @@ for (i = 1; i < argc; i++) /* -tls-on-connect: don't wait for STARTTLS (for old clients) */ #ifdef SUPPORT_TLS - else if (Ustrcmp(argrest, "ls-on-connect") == 0) tls_on_connect = TRUE; + else if (Ustrcmp(argrest, "ls-on-connect") == 0) tls_in.on_connect = TRUE; #endif else badarg = TRUE; @@ -3905,8 +3972,9 @@ if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0) { int i; uschar *p = big_buffer; - Ustrcpy(p, "cwd="); - (void)getcwd(CS p+4, big_buffer_size - 4); + char * dummy; + Ustrcpy(p, "cwd= (failed)"); + dummy = /* quieten compiler */ getcwd(CS p+4, big_buffer_size - 4); while (*p) p++; (void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc); while (*p) p++; @@ -3949,8 +4017,9 @@ privilege by now. Before the chdir, we try to ensure that the directory exists. if (Uchdir(spool_directory) != 0) { + int dummy; (void)directory_make(spool_directory, US"", SPOOL_DIRECTORY_MODE, FALSE); - (void)Uchdir(spool_directory); + dummy = /* quieten compiler */ Uchdir(spool_directory); } /* Handle calls with the -bi option. This is a sendmail option to rebuild *the* @@ -4093,7 +4162,7 @@ if (smtp_input) interface_address = host_ntoa(-1, &interface_sock, NULL, &interface_port); - if (host_is_tls_on_connect_port(interface_port)) tls_on_connect = TRUE; + if (host_is_tls_on_connect_port(interface_port)) tls_in.on_connect = TRUE; if (real_uid == root_uid || real_uid == exim_uid || interface_port < 1024) { @@ -4259,13 +4328,12 @@ if (msg_action_arg > 0 && msg_action != MSG_DELIVER && msg_action != MSG_LOAD) exit(yield); } -/* All the modes below here require the remaining configuration sections -to be read, except that we can skip over the ACL setting when delivering -specific messages, or doing a queue run. (For various testing cases we could -skip too, but as they are rare, it doesn't really matter.) The argument is TRUE -for skipping. */ +/* We used to set up here to skip reading the ACL section, on + (msg_action_arg > 0 || (queue_interval == 0 && !daemon_listen) +Now, since the intro of the ${acl } expansion, ACL definitions may be +needed in transports so we lost the optimisation. */ -readconf_rest(msg_action_arg > 0 || (queue_interval == 0 && !daemon_listen)); +readconf_rest(); /* The configuration data will have been read into POOL_PERM because we won't ever want to reset back past it. Change the current pool to POOL_MAIN. In fact, @@ -5398,7 +5466,11 @@ while (more) if (ftest_prefix != NULL) printf("Prefix = %s\n", ftest_prefix); if (ftest_suffix != NULL) printf("Suffix = %s\n", ftest_suffix); - (void)chdir("/"); /* Get away from wherever the user is running this from */ + if (chdir("/")) /* Get away from wherever the user is running this from */ + { + DEBUG(D_receive) debug_printf("chdir(\"/\") failed\n"); + exim_exit(EXIT_FAILURE); + } /* Now we run either a system filter test, or a user filter test, or both. In the latter case, headers added by the system filter will persist and be