-/* $Cambridge: exim/src/src/exim.c,v 1.14 2005/02/17 11:58:26 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.22 2005/06/28 10:23:35 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
if (devnull < 0) devnull = open("/dev/null", O_RDWR);
if (devnull < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
string_open_failed(errno, "/dev/null"));
- if (devnull != i) dup2(devnull, i);
+ if (devnull != i) (void)dup2(devnull, i);
}
}
-if (devnull > 2) close(devnull);
+if (devnull > 2) (void)close(devnull);
}
#ifdef SUPPORT_TLS
tls_close(FALSE); /* Shut down the TLS library */
#endif
- close(fileno(smtp_in));
- close(fileno(smtp_out));
+ (void)close(fileno(smtp_in));
+ (void)close(fileno(smtp_out));
smtp_in = NULL;
}
else
{
- close(0); /* stdin */
- if ((debug_selector & D_resolver) == 0) close(1); /* stdout */
- if (debug_selector == 0) /* stderr */
+ (void)close(0); /* stdin */
+ if ((debug_selector & D_resolver) == 0) (void)close(1); /* stdout */
+ if (debug_selector == 0) /* stderr */
{
if (!synchronous_delivery)
{
- close(2);
+ (void)close(2);
log_stderr = NULL;
}
(void)setsid();
*************************************************/
/* Called to extract the port from the values given to -oMa and -oMi.
-It also checks the syntax of the address.
+It also checks the syntax of the address, and terminates it before the
+port data when a port is extracted.
Argument:
address the address, with possible port on the end
for one). The top bit in the table means "put in 2nd selector". This does not
yet apply to debug options, so the "=" facility sets only the first selector.
+The "all" selector, which must be equal to 0xffffffff, is recognized specially.
+It sets all the bits in both selectors. However, there is a facility for then
+unsetting certain bits, because we want to turn off "memory" in the debug case.
+
A bad value for a debug setting is treated as an unknown option - error message
to stderr and die. For log settings, which come from the configuration file,
we write to the log on the way out...
Arguments:
selector1 address of the first bit string
selector2 address of the second bit string, or NULL
+ notall1 bits to exclude from "all" for selector1
+ notall2 bits to exclude from "all" for selector2
string the configured string
options the table of option names
count size of table
*/
static void
-decode_bits(unsigned int *selector1, unsigned int *selector2, uschar *string,
- bit_table *options, int count, uschar *which)
+decode_bits(unsigned int *selector1, unsigned int *selector2, int notall1,
+ int notall2, uschar *string, bit_table *options, int count, uschar *which)
{
uschar *errmsg;
if (string == NULL) return;
unsigned int bit = middle->bit;
unsigned int *selector;
- /* The value with all bits set means "set all bits in both selectors"
+ /* The value with all bits set means "force all bits in both selectors"
in the case where two are being handled. However, the top bit in the
- second selector is never set. */
+ second selector is never set. When setting, some bits can be excluded.
+ */
if (bit == 0xffffffff)
{
- *selector1 = adding? bit : 0;
- if (selector2 != NULL) *selector2 = adding? 0x7fffffff : 0;
+ if (adding)
+ {
+ *selector1 = 0xffffffff ^ notall1;
+ if (selector2 != NULL) *selector2 = 0x7fffffff ^ notall2;
+ }
+ else
+ {
+ *selector1 = 0;
+ if (selector2 != NULL) *selector2 = 0;
+ }
}
/* Otherwise, the 0x80000000 bit means "this value, without the top
#ifdef EXIM_PERL
fprintf(f, " Perl");
#endif
+#ifdef EXPAND_DLFUNC
+ fprintf(f, " Expand_dlfunc");
+#endif
#ifdef USE_TCP_WRAPPERS
fprintf(f, " TCPwrappers");
#endif
#ifdef EXPERIMENTAL_BRIGHTMAIL
fprintf(f, " Experimental_Brightmail");
#endif
+#ifdef EXPERIMENTAL_DOMAINKEYS
+ fprintf(f, " Experimental_DomainKeys");
+#endif
fprintf(f, "\n");
fprintf(f, "Lookups:");
argrest++;
}
if (*argrest != 0)
- decode_bits(&selector, NULL, argrest, debug_options,
+ decode_bits(&selector, NULL, D_memory, 0, argrest, debug_options,
debug_options_count, US"debug");
debug_selector = selector;
}
/* Handle the decoding of logging options. */
-decode_bits(&log_write_selector, &log_extra_selector, log_selector_string,
+decode_bits(&log_write_selector, &log_extra_selector, 0, 0, log_selector_string,
log_options, log_options_count, US"log");
DEBUG(D_any)
Don't attempt it if logging is disabled, or if listing variables or if
verifying/testing addresses or expansions. */
-if ((log_extra_selector & LX_arguments) != 0 && really_exim
- && !list_options && !checking)
+if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0)
+ && really_exim && !list_options && !checking)
{
int i;
uschar *p = big_buffer;
(p - big_buffer) - 4), printing, quote);
while (*p) p++;
}
- log_write(0, LOG_MAIN, "%s", big_buffer);
+
+ if ((log_extra_selector & LX_arguments) != 0)
+ log_write(0, LOG_MAIN, "%s", big_buffer);
+ else
+ debug_printf("%s\n", big_buffer);
}
/* Set the working directory to be the top-level spool directory. We don't rely
if (bi_option)
{
- fclose(config_file);
+ (void)fclose(config_file);
if (bi_command != NULL)
{
int i = 0;
if (smtp_input)
{
union sockaddr_46 inetd_sock;
- SOCKLEN_T size = sizeof(inetd_sock);
+ EXIM_SOCKLEN_T size = sizeof(inetd_sock);
if (getpeername(0, (struct sockaddr *)(&inetd_sock), &size) == 0)
{
int family = ((struct sockaddr *)(&inetd_sock))->sa_family;
/* Run in daemon and/or queue-running mode. The function daemon_go() never
returns. We leave this till here so that the originator_ fields are available
-for incoming messages via the daemon. */
+for incoming messages via the daemon. The daemon cannot be run in mua_wrapper
+mode. */
if (daemon_listen || queue_interval > 0)
{
- if (mua_wrapper) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Daemon cannot be "
- "run when mua_wrapper is set");
+ if (mua_wrapper)
+ {
+ fprintf(stderr, "Daemon cannot be run when mua_wrapper is set\n");
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Daemon cannot be run when "
+ "mua_wrapper is set");
+ }
daemon_go();
}
else if (is_inetd)
{
- fclose(stderr);
+ (void)fclose(stderr);
exim_nullstd(); /* Re-open to /dev/null */
verify_get_ident(IDENT_PORT);
host_build_sender_fullhost();
if exim is started from inetd. In this case fd 0 will be set to the socket,
but fd 1 will not be set. This also happens for passed SMTP channels. */
-if (fstat(1, &statbuf) < 0) dup2(0, 1);
+if (fstat(1, &statbuf) < 0) (void)dup2(0, 1);
/* Set up the incoming protocol name and the state of the program. Root
is allowed to force received protocol via the -oMr option above, and if we are
if (ftest_prefix != NULL) printf("Prefix = %s\n", ftest_prefix);
if (ftest_suffix != NULL) printf("Suffix = %s\n", ftest_suffix);
- chdir("/"); /* Get away from wherever the user is running this from */
+ (void)chdir("/"); /* Get away from wherever the user is running this from */
/* 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
close_unwanted(); /* Close unwanted file descriptors and TLS */
exim_nullstd(); /* Ensure std{in,out,err} exist */
+ /* Occasionally in the test harness we don't have synchronous delivery
+ set (can happen with bounces). In that case, let the old process finish
+ before continuing, to keep the debug output the same. */
+
+ if (running_in_test_harness && !synchronous_delivery) millisleep(100);
+
/* Re-exec Exim if we need to regain privilege (note: in mua_wrapper
mode, deliver_drop_privilege is forced TRUE). */