log_write(0, LOG_MAIN|LOG_PANIC, "backtrace");
log_write(0, LOG_MAIN|LOG_PANIC, "---");
+
+/* This function is officially not callable from a signal handler, as it
+calls malloc() for the returned data. However, it seems to work - and we
+know we're going on to crash anyway - so just hold our noses and do it.
+A alternative might be backtrace_symbols_fd(). */
+
if ((ss = backtrace_symbols(buf, nptrs)))
{
for (int i = 0; i < nptrs; i++)
if (fd < 0) return;
-(void)write(fd, process_info, process_info_len);
+if (write(fd, process_info, process_info_len) != 0) ;
(void)close(fd);
}
return item;
}
+/* as above, copying as tainted */
+static inline const uschar *
+exim_arg_copy(const uschar * item, int maxlen, const char * description)
+{
+return string_copy_taint(exim_str_fail_toolong(item, maxlen, description),
+ GET_TAINTED);
+}
+
/* exim_chown_failure() called from exim_chown()/exim_fchown() on failure
of chown()/fchown(). See src/functions.h for more explanation */
int
#ifdef WITH_CONTENT_SCAN
g = string_cat(g, US" Content_Scanning");
#endif
+#ifndef DISABLE_EXIM_FILTER
+ g = string_cat(g, US" Exim_filter");
+#endif
+#ifndef DISABLE_SIEVE_FILTER
+ g = string_cat(g, US" Sieve_filter");
+#endif
#ifdef SUPPORT_CRYPTEQ
g = string_cat(g, US" crypteq");
#endif
# ifdef __VERSION__
g = string_fmt_append(g, "Compiler: GCC [%s]\n", __VERSION__);
# else
- g = string_fmt_append(g, "Compiler: GCC [%s]\n", "? unknown version ?";
+ g = string_fmt_append(g, "Compiler: GCC [%s]\n", "? unknown version ?");
# endif
#else
g = string_cat(g, US"Compiler: <unknown>\n");
);
return;
case CMDINFO_SIEVE:
- for (const uschar ** pp = exim_sieve_extension_list; *pp; ++pp)
- fprintf(stream, "%s\n", *pp);
+ {
+ const misc_module_info * mi;
+ typedef void (*fn_t)(FILE *);
+ if ((mi = misc_mod_find(US"sieve_filter", NULL)))
+ (((fn_t *) mi->functions)[SIEVE_EXTENSIONS]) (stream);
+ else
+ fprintf(stream, "Sieve filtering not available\n");
+ }
return;
case CMDINFO_DSCP:
dscp_list_to_stream(stream);
/* sendmail uses -Ac and -Am to control which .cf file is used;
we ignore them. */
case 'A':
- if (!*argrest) { badarg = TRUE; break; }
- else
- {
- BOOL ignore = FALSE;
- switch (*argrest)
- {
- case 'c':
- case 'm':
- if (*(argrest + 1) == '\0')
- ignore = TRUE;
- break;
- }
- if (!ignore) badarg = TRUE;
- }
- break;
+ if (!*argrest) { badarg = TRUE; break; }
+ else
+ {
+ BOOL ignore = FALSE;
+ switch (*argrest)
+ {
+ case 'c':
+ case 'm':
+ if (*(argrest + 1) == '\0')
+ ignore = TRUE;
+ break;
+ }
+ if (!ignore) badarg = TRUE;
+ }
+ break;
+
+ /* -atrn <host> <domains> */
+ case 'a':
+ if (Ustrcmp(argrest, "trn") == 0)
+ if (i+2 < argc)
+ {
+ atrn_mode = US"C"; /* Customer mode */
+
+ /* The host could at this point have a port attached */
+ atrn_host = exim_arg_copy(argv[++i], EXIM_DOMAINNAME_MAX, "-atrn");
+ atrn_domains = exim_arg_copy(argv[++i], EXIM_DOMAINNAME_MAX*4,
+ "-atrn");
+ i++;
+ }
+ else
+ exim_fail("exim: host and domainlist expected after %s\n", argv[i]);
+ else badarg = TRUE;
+ break;
/* -Btype is a sendmail option for 7bit/8bit setting. Exim is 8-bit clean
so has no need of it. */
case 'B':
- if (!*argrest) i++; /* Skip over the type */
- break;
+ if (!*argrest) i++; /* Skip over the type */
+ break;
case 'b':
/* -bw: inetd wait mode, accept a listening socket as stdin */
case 'w':
- f.inetd_wait_mode = TRUE;
+ f.inetd_wait_mode = f.daemon_listen = f.daemon_scion = TRUE;
f.background_daemon = FALSE;
- f.daemon_listen = f.daemon_scion = TRUE;
if (*argrest)
if ((inetd_wait_timeout = readconf_readtime(argrest, 0, FALSE)) <= 0)
exim_fail("exim: bad time value %s: abandoned\n", argv[i]);
if (usage_wanted) exim_usage(called_as);
/* Arguments have been processed. Check for incompatibilities. */
-if ( ( (smtp_input || extract_recipients || recipients_arg < argc)
+if ( (smtp_input || extract_recipients || recipients_arg < argc)
&& ( f.daemon_listen || qrunners || bi_option
|| test_retry_arg >= 0 || test_rewrite_arg >= 0
|| filter_test != FTEST_NONE
|| msg_action_arg > 0 && !one_msg_action
- ) )
- || ( msg_action_arg > 0
+ )
+ || msg_action_arg > 0
&& ( f.daemon_listen || is_multiple_qrun() || list_options
|| checking && msg_action != MSG_LOAD
|| bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0
- ) )
- || ( (f.daemon_listen || is_multiple_qrun())
+ )
+ || (f.daemon_listen || is_multiple_qrun())
&& ( sender_address || list_options || list_queue || checking
|| bi_option
- ) )
+ )
|| f.daemon_listen && is_onetime_qrun()
|| f.inetd_wait_mode && qrunners
- || ( list_options
+ || list_options
&& ( checking || smtp_input || extract_recipients
|| filter_test != FTEST_NONE || bi_option
- ) )
- || ( verify_address_mode
+ )
+ || verify_address_mode
&& ( f.address_test_mode || smtp_input || extract_recipients
|| filter_test != FTEST_NONE || bi_option
- ) )
- || ( f.address_test_mode
+ )
+ || f.address_test_mode
&& ( smtp_input || extract_recipients || filter_test != FTEST_NONE
|| bi_option
- ) )
- || ( smtp_input
+ )
+ || smtp_input
&& (sender_address || filter_test != FTEST_NONE || extract_recipients)
- )
|| deliver_selectstring && !qrunners
|| msg_action == MSG_LOAD && (!expansion_test || expansion_test_message)
+ || atrn_mode
+ && ( f.daemon_listen || expansion_test || filter_test != FTEST_NONE
+ || checking /* || bi_option || info_stdout || receiving_message
+ || malware_test_file || list_queue || list_config || list_options
+ || version_printed || msg_action_arg > 0 || qrunners
+ */
+ )
)
exim_fail("exim: incompatible command-line options or arguments\n");
if (Uchdir(spool_directory) != 0)
{
(void) directory_make(spool_directory, US"", SPOOL_DIRECTORY_MODE, FALSE);
- (void) Uchdir(spool_directory);
+ if (Uchdir(spool_directory) < 0) ;
}
/* Handle calls with the -bi option. This is a sendmail option to rebuild *the*
if (real_uid == root_uid || real_uid == exim_uid || interface_port < 1024)
{
+ if (mua_wrapper) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Input from "
+ "inetd is not supported when mua_wrapper is set");
f.is_inetd = TRUE;
sender_host_address = host_ntoa(-1, (struct sockaddr *)(&inetd_sock),
NULL, &sender_host_port);
- if (mua_wrapper) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Input from "
- "inetd is not supported when mua_wrapper is set");
}
else
exim_fail(
#ifdef LOAD_AVG_NEEDS_ROOT
if ( receiving_message
- && (queue_only_load >= 0 || (f.is_inetd && smtp_load_reserve >= 0)))
+ && (queue_only_load >= 0 || f.is_inetd && smtp_load_reserve >= 0))
load_average = OS_GETLOADAVG();
#endif
#endif
daemon_go();
+ /*NOTREACHED*/
}
/* If the sender ident has not been set (by a trusted caller) set it to
/* Expand command line items */
if (recipients_arg < argc)
- while (recipients_arg < argc)
- expansion_test_line(exim_str_fail_toolong(argv[recipients_arg++], EXIM_EMAILADDR_MAX, "recipient"));
+ {
+ config_filename = US"-be args";
+ for (config_lineno = 1; recipients_arg < argc; config_lineno++)
+ expansion_test_line(exim_str_fail_toolong(argv[recipients_arg++],
+ EXIM_EMAILADDR_MAX, "-be arg"));
+ }
/* Read stdin */
void *dlhandle = set_readline(&fn_readline, &fn_addhist);
#endif
- while (s = get_stdinput(fn_readline, fn_addhist))
+ config_filename = US"-be stdin";
+ for (config_lineno = 1; s = get_stdinput(fn_readline, fn_addhist);
+ config_lineno++)
expansion_test_line(s);
#ifdef USE_READLINE
verification test or info dump.
In the former case, show the configuration file name. */
-if (recipients_arg >= argc && !extract_recipients && !smtp_input)
+if ( recipients_arg >= argc && !extract_recipients
+ && !smtp_input && !atrn_mode)
{
if (version_printed)
{
exim_usage(called_as);
}
+/*XXX somewhere around here. Maybe earlier, but no later. ATRN customer */
+if (atrn_mode)
+ atrn_handle_customer();
+
/* If mua_wrapper is set, Exim is being used to turn an MUA that submits on the
standard input into an MUA that submits to a smarthost over TCP/IP. We know
logging being sent down the socket and make an identd call to get the
sender_ident. */
-else if (f.is_inetd)
+else if (f.is_inetd && !atrn_mode)
{
(void)fclose(stderr);
exim_nullstd(); /* Re-open to /dev/null */
{
smtp_in = stdin;
smtp_out = stdout;
+
memset(sender_host_cache, 0, sizeof(sender_host_cache));
if (verify_check_host(&hosts_connection_nolog) == OK)
{
rmark reset_point = store_mark();
message_id[0] = 0;
- /* Handle the SMTP case; call smtp_setup_mst() to deal with the initial SMTP
+ /* Handle the SMTP case; call smtp_setup_msg() to deal with the initial SMTP
input and build the recipients list, before calling receive_msg() to read the
message proper. Whatever sender address is given in the SMTP transaction is
often ignored for local senders - we use the actual sender, which is normally