#include "exim.h"
+#ifdef __GLIBC__
+# include <gnu/libc-version.h>
+#endif
+
#ifdef USE_GNUTLS
# include <gnutls/gnutls.h>
# if GNUTLS_VERSION_NUMBER < 0x030103 && !defined(DISABLE_OCSP)
#ifdef SUPPORT_SOCKS
fprintf(f, " SOCKS");
#endif
+#ifdef EXPERIMENTAL_LMDB
+ fprintf(f, " Experimental_LMDB");
+#endif
#ifdef EXPERIMENTAL_SPF
fprintf(f, " Experimental_SPF");
#endif
#if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
fprintf(f, " ldap ldapdn ldapm");
#endif
+#ifdef EXPERIMENTAL_LMDB
+ fprintf(f, " lmdb");
+#endif
#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
fprintf(f, " mysql");
#endif
fprintf(f, "Compiler: <unknown>\n");
#endif
+#ifdef __GLIBC__
+ fprintf(f, "Library version: Glibc: Compile: %d.%d\n",
+ __GLIBC__, __GLIBC_MINOR__);
+ if (__GLIBC_PREREQ(2, 1))
+ fprintf(f, " Runtime: %s\n",
+ gnu_get_libc_version());
+#endif
+
#ifdef SUPPORT_TLS
tls_version_report(f);
#endif
characters; unless it's an ancient version of PCRE in which case it
is not defined. */
#ifndef PCRE_PRERELEASE
-#define PCRE_PRERELEASE
+# define PCRE_PRERELEASE
#endif
#define QUOTE(X) #X
#define EXPAND_AND_QUOTE(X) QUOTE(X)
/* Ensure we have a buffer for constructing log entries. Use malloc directly,
because store_malloc writes a log entry on failure. */
-log_buffer = (uschar *)malloc(LOG_BUFFER_SIZE);
-if (log_buffer == NULL)
+if (!(log_buffer = US malloc(LOG_BUFFER_SIZE)))
{
fprintf(stderr, "exim: failed to get store for log buffer\n");
exit(EXIT_FAILURE);
sender_host_address = argv[i];
host_checking = checking = log_testing_mode = TRUE;
host_checking_callout = argrest[1] == 'c';
+ message_logs = FALSE;
}
/* -bi: This option is used by sendmail to initialize *the* alias file,
break;
}
+ else if (*argrest == 'C' && argrest[1] && !argrest[2])
+ {
+ switch(argrest[1])
+ {
/* -MCA: set the smtp_authenticated flag; this is useful only when it
precedes -MC (see above). The flag indicates that the host to which
Exim is connected has accepted an AUTH sequence. */
- else if (Ustrcmp(argrest, "CA") == 0)
- {
- smtp_authenticated = TRUE;
- break;
- }
+ case 'A': smtp_authenticated = TRUE; break;
/* -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;
- }
+ case 'D': smtp_peer_options |= PEER_OFFERED_DSN; break;
- /* -MCG: set the queue name, to a non-default value
+ /* -MCG: set the queue name, to a non-default value */
- else if (Ustrcmp(argrest, "CG") == 0)
- {
- if (++i < argc) queue_name = string_copy(argv[i]);
- else badarg = TRUE;
- break;
- }
+ case 'G': if (++i < argc) queue_name = string_copy(argv[i]);
+ else badarg = TRUE;
+ break;
+
+ /* -MCK: the peer offered CHUNKING. Must precede -MC */
+
+ case 'K': smtp_peer_options |= PEER_OFFERED_CHUNKING; break;
/* -MCP: set the smtp_use_pipelining flag; this is useful only when
it preceded -MC (see above) */
- else if (Ustrcmp(argrest, "CP") == 0)
- {
- smtp_use_pipelining = TRUE;
- break;
- }
+ case 'P': smtp_peer_options |= PEER_OFFERED_PIPE; break;
/* -MCQ: pass on the pid of the queue-running process that started
this chain of deliveries and the fd of its synchronizing pipe; this
is useful only when it precedes -MC (see above) */
- else if (Ustrcmp(argrest, "CQ") == 0)
- {
- if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i]));
- else badarg = TRUE;
- if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i]));
- else badarg = TRUE;
- break;
- }
+ case 'Q': if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i]));
+ else badarg = TRUE;
+ if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i]));
+ else badarg = TRUE;
+ break;
/* -MCS: set the smtp_use_size flag; this is useful only when it
precedes -MC (see above) */
- else if (Ustrcmp(argrest, "CS") == 0)
- {
- smtp_use_size = TRUE;
- break;
- }
+ case 'S': smtp_peer_options |= PEER_OFFERED_SIZE; break;
+#ifdef SUPPORT_TLS
/* -MCT: set the tls_offered flag; this is useful only when it
precedes -MC (see above). The flag indicates that the host to which
Exim is connected has offered TLS support. */
- #ifdef SUPPORT_TLS
- else if (Ustrcmp(argrest, "CT") == 0)
- {
- tls_offered = TRUE;
- break;
+ case 'T': smtp_peer_options |= PEER_OFFERED_TLS; break;
+#endif
+
+ default: badarg = TRUE; break;
+ }
+ break;
}
- #endif
/* -M[x]: various operations on the following list of message ids:
-M deliver the messages, ignoring next retry times and thawing
if (*argrest == 'f')
{
queue_run_force = TRUE;
- if (*(++argrest) == 'f')
+ if (*++argrest == 'f')
{
deliver_force_thaw = TRUE;
argrest++;
argrest++;
}
- /* -q[f][f][l][G<name>]... Run the named queue */
+ /* -q[f][f][l][G<name>]... Work on the named queue */
if (*argrest == 'G')
{
- queue_name = string_copy(argrest+1);
- do ++argrest; while (*argrest);
+ int i;
+ for (argrest++, i = 0; argrest[i] && argrest[i] != '/'; ) i++;
+ queue_name = string_copyn(argrest, i);
+ argrest += i;
+ if (*argrest == '/') argrest++;
}
/* -q[f][f][l][G<name>]: Run the queue, optionally forced, optionally local
stop_queue_run_id = argv[++i];
}
- /* -q[f][f][l]<n>: Run the queue at regular intervals, optionally forced,
- optionally local only. */
+ /* -q[f][f][l][G<name>/]<n>: Run the queue at regular intervals, optionally
+ forced, optionally local only, optionally named. */
- else
+ else if ((queue_interval = readconf_readtime(*argrest ? argrest : argv[++i],
+ 0, FALSE)) <= 0)
{
- if (*argrest != 0)
- queue_interval = readconf_readtime(argrest, 0, FALSE);
- else
- queue_interval = readconf_readtime(argv[++i], 0, FALSE);
- if (queue_interval <= 0)
- {
- fprintf(stderr, "exim: bad time value %s: abandoned\n", argv[i]);
- exit(EXIT_FAILURE);
- }
+ fprintf(stderr, "exim: bad time value %s: abandoned\n", argv[i]);
+ exit(EXIT_FAILURE);
}
break;
if (*argrest != 0)
{
int i;
- for (i = 0; i < sizeof(rsopts)/sizeof(uschar *); i++)
- {
+ for (i = 0; i < nelem(rsopts); i++)
if (Ustrcmp(argrest, rsopts[i]) == 0)
{
if (i != 2) queue_run_force = TRUE;
if (i == 1 || i == 4) deliver_force_thaw = TRUE;
argrest += Ustrlen(rsopts[i]);
}
- }
}
/* -R: Set string to match in addresses for forced queue run to
pick out particular messages. */
- if (*argrest == 0)
+ if (*argrest)
+ deliver_selectstring = argrest;
+ else if (i+1 < argc)
+ deliver_selectstring = argv[++i];
+ else
{
- if (i+1 < argc) deliver_selectstring = argv[++i]; else
- {
- fprintf(stderr, "exim: string expected after -R\n");
- exit(EXIT_FAILURE);
- }
+ fprintf(stderr, "exim: string expected after -R\n");
+ exit(EXIT_FAILURE);
}
- else deliver_selectstring = argrest;
break;
in all cases provided there are no further characters in this
argument. */
- if (*argrest != 0)
+ if (*argrest)
{
int i;
- for (i = 0; i < sizeof(rsopts)/sizeof(uschar *); i++)
- {
+ for (i = 0; i < nelem(rsopts); i++)
if (Ustrcmp(argrest, rsopts[i]) == 0)
{
if (i != 2) queue_run_force = TRUE;
if (i == 1 || i == 4) deliver_force_thaw = TRUE;
argrest += Ustrlen(rsopts[i]);
}
- }
}
/* -S: Set string to match in addresses for forced queue run to
pick out particular messages. */
- if (*argrest == 0)
+ if (*argrest)
+ deliver_selectstring_sender = argrest;
+ else if (i+1 < argc)
+ deliver_selectstring_sender = argv[++i];
+ else
{
- if (i+1 < argc) deliver_selectstring_sender = argv[++i]; else
- {
- fprintf(stderr, "exim: string expected after -S\n");
- exit(EXIT_FAILURE);
- }
+ fprintf(stderr, "exim: string expected after -S\n");
+ exit(EXIT_FAILURE);
}
- else deliver_selectstring_sender = argrest;
break;
/* -Tqt is an option that is exclusively for use by the testing suite.
/* If -R or -S have been specified without -q, assume a single queue run. */
-if ((deliver_selectstring != NULL || deliver_selectstring_sender != NULL) &&
- queue_interval < 0) queue_interval = 0;
+if ( (deliver_selectstring || deliver_selectstring_sender)
+ && queue_interval < 0)
+ queue_interval = 0;
END_ARG:
) ||
(
msg_action_arg > 0 &&
- (daemon_listen || queue_interval >= 0 || list_options ||
+ (daemon_listen || queue_interval > 0 || list_options ||
(checking && msg_action != MSG_LOAD) ||
bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0)
) ||
(
- (daemon_listen || queue_interval >= 0) &&
+ (daemon_listen || queue_interval > 0) &&
(sender_address != NULL || list_options || list_queue || checking ||
bi_option)
) ||
"syslog_processname is longer than 32 chars: aborting");
if (log_oneline)
- {
if (admin_user)
{
log_write(0, LOG_MAIN, "%s", log_oneline);
}
else
return EXIT_FAILURE;
- }
/* In some operating systems, the environment variable TMPDIR controls where
temporary files are created; Exim doesn't use these (apart from when delivering
#ifdef EXIM_TMPDIR
{
uschar **p;
- if (environ) for (p = USS environ; *p != NULL; p++)
- {
- if (Ustrncmp(*p, "TMPDIR=", 7) == 0 &&
- Ustrcmp(*p+7, EXIM_TMPDIR) != 0)
+ if (environ) for (p = USS environ; *p; p++)
+ if (Ustrncmp(*p, "TMPDIR=", 7) == 0 && Ustrcmp(*p+7, EXIM_TMPDIR) != 0)
{
- uschar *newp = malloc(Ustrlen(EXIM_TMPDIR) + 8);
+ uschar * newp = store_malloc(Ustrlen(EXIM_TMPDIR) + 8);
sprintf(CS newp, "TMPDIR=%s", EXIM_TMPDIR);
*p = newp;
DEBUG(D_any) debug_printf("reset TMPDIR=%s in environment\n", EXIM_TMPDIR);
}
- }
}
#endif
this. We have to make a new environment if TZ is wrong, but don't bother if
timestamps_utc is set, because then all times are in UTC anyway. */
-if (timezone_string != NULL && strcmpic(timezone_string, US"UTC") == 0)
- {
+if (timezone_string && strcmpic(timezone_string, US"UTC") == 0)
timestamps_utc = TRUE;
- }
else
{
uschar *envtz = US getenv("TZ");
- if ((envtz == NULL && timezone_string != NULL) ||
- (envtz != NULL &&
- (timezone_string == NULL ||
- Ustrcmp(timezone_string, envtz) != 0)))
+ if (envtz ? !timezone_string || Ustrcmp(timezone_string, envtz) != 0 : timezone_string)
{
uschar **p = USS environ;
uschar **new;
uschar **newp;
int count = 0;
- if (environ) while (*p++ != NULL) count++;
- if (envtz == NULL) count++;
- newp = new = malloc(sizeof(uschar *) * (count + 1));
- if (environ) for (p = USS environ; *p != NULL; p++)
- {
- if (Ustrncmp(*p, "TZ=", 3) == 0) continue;
- *newp++ = *p;
- }
- if (timezone_string != NULL)
+ if (environ) while (*p++) count++;
+ if (!envtz) count++;
+ newp = new = store_malloc(sizeof(uschar *) * (count + 1));
+ if (environ) for (p = USS environ; *p; p++)
+ if (Ustrncmp(*p, "TZ=", 3) != 0) *newp++ = *p;
+ if (timezone_string)
{
- *newp = malloc(Ustrlen(timezone_string) + 4);
+ *newp = store_malloc(Ustrlen(timezone_string) + 4);
sprintf(CS *newp++, "TZ=%s", timezone_string);
}
*newp = NULL;
(stop_queue_run_id == NULL)? US"" : US" stopping at ",
(stop_queue_run_id == NULL)? US"" : stop_queue_run_id);
if (*queue_name)
- set_process_info(CS string_sprintf(
- "running the '%s' queue (single queue run)", queue_name));
+ set_process_info("running the '%s' queue (single queue run)", queue_name);
else
set_process_info("running the queue (single queue run)");
queue_run(start_queue_run_id, stop_queue_run_id, FALSE);
if (geteuid() != root_uid && !deliver_drop_privilege && !unprivileged)
{
- (void)child_exec_exim(CEE_EXEC_EXIT, FALSE, NULL, FALSE, 2, US"-Mc",
- message_id);
+ (void)child_exec_exim(CEE_EXEC_EXIT, FALSE, NULL, FALSE,
+ 2, US"-Mc", message_id);
/* Control does not return here. */
}