-/* $Cambridge: exim/src/src/exim.c,v 1.7 2004/11/04 12:19:48 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.11 2004/12/16 15:11:47 tom Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
fprintf(f, " OpenSSL");
#endif
#endif
+#ifdef WITH_CONTENT_SCAN
+ fprintf(f, " Content_Scanning");
+#endif
+#ifdef WITH_OLD_DEMIME
+ fprintf(f, " Old_Demime");
+#endif
+#ifdef EXPERIMENTAL_SPF
+ fprintf(f, " Experimental_SPF");
+#endif
+#ifdef EXPERIMENTAL_SRS
+ fprintf(f, " Experimental_SRS");
+#endif
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ fprintf(f, " Experimental_Brightmail");
+#endif
fprintf(f, "\n");
fprintf(f, "Lookups:");
int arg_receive_timeout = -1;
int arg_smtp_receive_timeout = -1;
int arg_error_handling = error_handling;
-int filter_fd = -1;
+int filter_sfd = -1;
+int filter_ufd = -1;
int group_count;
int i;
int list_queue_option = 0;
uschar *ftest_suffix = NULL;
uschar *real_sender_address;
uschar *originator_home = US"/";
-BOOL ftest_system = FALSE;
void *reset_point;
struct passwd *pw;
else if (*argrest == 'e')
expansion_test = checking = TRUE;
- /* -bf: Run in mail filter testing mode
- -bF: Ditto, but for system filters
+ /* -bF: Run system filter test */
+
+ else if (*argrest == 'F')
+ {
+ filter_test |= FTEST_SYSTEM;
+ if (*(++argrest) != 0) { badarg = TRUE; break; }
+ if (++i < argc) filter_test_sfile = argv[i]; else
+ {
+ fprintf(stderr, "exim: file name expected after %s\n", argv[i-1]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* -bf: Run user filter test
-bfd: Set domain for filter testing
-bfl: Set local part for filter testing
-bfp: Set prefix for filter testing
-bfs: Set suffix for filter testing
*/
- else if (*argrest == 'f' || *argrest == 'F')
+ else if (*argrest == 'f')
{
- ftest_system = *argrest++ == 'F';
- if (*argrest == 0)
+ if (*(++argrest) == 0)
{
- if(++i < argc) filter_test = argv[i]; else
+ filter_test |= FTEST_USER;
+ if (++i < argc) filter_test_ufile = argv[i]; else
{
fprintf(stderr, "exim: file name expected after %s\n", argv[i-1]);
exit(EXIT_FAILURE);
break;
/* -d: Set debug level (see also -v below) or set the drop_cr option.
- The latter is now a no-opt, retained for compatibility only. */
+ The latter is now a no-op, retained for compatibility only. If -dd is used,
+ debugging subprocesses of the daemon is disabled. */
case 'd':
if (Ustrcmp(argrest, "ropcr") == 0)
unsigned int selector = D_default;
debug_selector = 0;
debug_file = NULL;
+ if (*argrest == 'd')
+ {
+ debug_daemon = TRUE;
+ argrest++;
+ }
if (*argrest != 0)
decode_bits(&selector, NULL, argrest, debug_options,
debug_options_count, US"debug");
(smtp_input || extract_recipients || recipients_arg < argc) &&
(daemon_listen || queue_interval >= 0 || bi_option ||
test_retry_arg >= 0 || test_rewrite_arg >= 0 ||
- filter_test != NULL || (msg_action_arg > 0 && !one_msg_action))
+ filter_test != FTEST_NONE || (msg_action_arg > 0 && !one_msg_action))
) ||
(
msg_action_arg > 0 &&
(
list_options &&
(checking || smtp_input || extract_recipients ||
- filter_test != NULL || bi_option)
+ filter_test != FTEST_NONE || bi_option)
) ||
(
verify_address_mode &&
(address_test_mode || smtp_input || extract_recipients ||
- filter_test != NULL || bi_option)
+ filter_test != FTEST_NONE || bi_option)
) ||
(
address_test_mode && (smtp_input || extract_recipients ||
- filter_test != NULL || bi_option)
+ filter_test != FTEST_NONE || bi_option)
) ||
(
- smtp_input && (sender_address != NULL || filter_test != NULL ||
+ smtp_input && (sender_address != NULL || filter_test != FTEST_NONE ||
extract_recipients)
) ||
(
) || /* OR */
expansion_test /* expansion testing */
|| /* OR */
- filter_test != NULL) /* Filter testing */
+ filter_test != FTEST_NONE) /* Filter testing */
{
setgroups(group_count, group_list);
exim_setugid(real_uid, real_gid, FALSE,
else exim_setugid(geteuid(), getegid(), FALSE, US"forcing real = effective");
-/* If testing a filter, open the file now, before wasting time doing other
+/* If testing a filter, open the file(s) now, before wasting time doing other
setups and reading the message. */
-if (filter_test != NULL)
+if ((filter_test & FTEST_SYSTEM) != 0)
+ {
+ filter_sfd = Uopen(filter_test_sfile, O_RDONLY, 0);
+ if (filter_sfd < 0)
+ {
+ fprintf(stderr, "exim: failed to open %s: %s\n", filter_test_sfile,
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+ }
+
+if ((filter_test & FTEST_USER) != 0)
{
- filter_fd = Uopen(filter_test, O_RDONLY,0);
- if (filter_fd < 0)
+ filter_ufd = Uopen(filter_test_ufile, O_RDONLY, 0);
+ if (filter_ufd < 0)
{
- fprintf(stderr, "exim: failed to open %s: %s\n", filter_test,
+ fprintf(stderr, "exim: failed to open %s: %s\n", filter_test_ufile,
strerror(errno));
return EXIT_FAILURE;
}
}
/* If the caller is not trusted, certain arguments are ignored when running for
-real, but are permitted when checking things (-be, -bv, -bt, -bh, -bf). Note
-that authority for performing certain actions on messages is tested in the
+real, but are permitted when checking things (-be, -bv, -bt, -bh, -bf, -bF).
+Note that authority for performing certain actions on messages is tested in the
queue_action() function. */
-if (!trusted_caller && !checking && filter_test == NULL)
+if (!trusted_caller && !checking && filter_test == FTEST_NONE)
{
sender_host_name = sender_host_address = interface_address =
sender_ident = received_protocol = NULL;
if (originator_name == NULL)
{
if (sender_address == NULL ||
- (!trusted_caller && filter_test == NULL))
+ (!trusted_caller && filter_test == FTEST_NONE))
{
uschar *name = US pw->pw_gecos;
uschar *amp = Ustrchr(name, '&');
message via SMTP (inetd invocation or otherwise). */
if ((sender_address == NULL && !smtp_input) ||
- (!trusted_caller && filter_test == NULL))
+ (!trusted_caller && filter_test == FTEST_NONE))
{
sender_local = TRUE;
|| /* OR */
(sender_address[0] != 0 && /* Non-empty sender address, AND */
!checking && /* Not running tests, AND */
- filter_test == NULL)) /* Not testing a filter */
+ filter_test == FTEST_NONE)) /* Not testing a filter */
{
sender_address = originator_login;
sender_address_forced = FALSE;
if (host_checking)
{
+ int x[4];
+ int size;
+
sender_ident = NULL;
if (running_in_test_harness && sender_host_port != 0 &&
interface_address != NULL && interface_port != 0)
verify_get_ident(1413);
+
+ /* In case the given address is a non-canonical IPv6 address, canonicize
+ it. The code works for both IPv4 and IPv6, as it happens. */
+
+ size = host_aton(sender_host_address, x);
+ sender_host_address = store_get(48); /* large enough for full IPv6 */
+ (void)host_nmtoa(size, x, -1, sender_host_address, ':');
+
+ /* Now set up for testing */
host_build_sender_fullhost();
smtp_input = TRUE;
printf("Configuration file is %s\n", config_main_filename);
return EXIT_SUCCESS;
}
- if (filter_test == NULL)
+ if (filter_test == FTEST_NONE)
{
fprintf(stderr,
"Exim is a Mail Transfer Agent. It is normally called by Mail User Agents,\n"
}
}
- /* Read the data for the message. If filter_test is true, this will
- just read the headers for the message, and not write anything onto
- the spool. */
+ /* Read the data for the message. If filter_test is not FTEST_NONE, this
+ will just read the headers for the message, and not write anything onto the
+ spool. */
message_ended = END_NOTENDED;
more = receive_msg(extract_recipients);
unless specified. The the return path is set to to the sender unless it has
already been set from a return-path header in the message. */
- if (filter_test != NULL)
+ if (filter_test != FTEST_NONE)
{
deliver_domain = (ftest_domain != NULL)?
ftest_domain : qualify_domain_recipient;
if (ftest_suffix != NULL) printf("Suffix = %s\n", ftest_suffix);
chdir("/"); /* Get away from wherever the user is running this from */
- exim_exit(filter_runtest(filter_fd, ftest_system, more)?
- EXIT_SUCCESS : 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
+ available to the user filter. We need to copy the filter variables
+ explicitly. */
+
+ if ((filter_test & FTEST_SYSTEM) != 0)
+ {
+ if (!filter_runtest(filter_sfd, filter_test_sfile, TRUE, more))
+ exim_exit(EXIT_FAILURE);
+ }
+
+ memcpy(filter_sn, filter_n, sizeof(filter_sn));
+
+ if ((filter_test & FTEST_USER) != 0)
+ {
+ if (!filter_runtest(filter_ufd, filter_test_ufile, FALSE, more))
+ exim_exit(EXIT_FAILURE);
+ }
+
+ exim_exit(EXIT_SUCCESS);
}
/* Else act on the result of message reception. We should not get here unless