static void *
function_store_get(size_t size)
{
-return store_get((int)size);
+/* For now, regard all RE results as potentially tainted. We might need
+more intelligence on this point. */
+return store_get((int)size, TRUE);
}
static void
if (n == 0) n = EXPAND_MAXN + 1;
if (yield)
{
- int nn;
expand_nmax = setup < 0 ? 0 : setup + 1;
- for (nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
+ for (int nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
{
expand_nstring[expand_nmax] = s + ovector[nn];
expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
void
set_process_info(const char *format, ...)
{
-int len = sprintf(CS process_info, "%5d ", (int)getpid());
+gstring gs = { .size = PROCESS_INFO_SIZE - 2, .ptr = 0, .s = process_info };
+gstring * g;
+int len;
va_list ap;
+
+g = string_fmt_append(&gs, "%5d ", (int)getpid());
+len = g->ptr;
va_start(ap, format);
-if (!string_vformat(process_info + len, PROCESS_INFO_SIZE - len - 2, format, ap))
- Ustrcpy(process_info + len, "**** string overflowed buffer ****");
-len = Ustrlen(process_info);
-process_info[len+0] = '\n';
-process_info[len+1] = '\0';
-process_info_len = len + 1;
+if (!string_vformat(g, 0, format, ap))
+ {
+ gs.ptr = len;
+ g = string_cat(&gs, US"**** string overflowed buffer ****");
+ }
+g = string_catn(g, US"\n", 1);
+string_from_gstring(g);
+process_info_len = g->ptr;
DEBUG(D_process_info) debug_printf("set_process_info: %s", process_info);
va_end(ap);
}
}
-
-
/*************************************************
* Ensure stdin, stdout, and stderr exist *
*************************************************/
void
exim_nullstd(void)
{
-int i;
int devnull = -1;
struct stat statbuf;
-for (i = 0; i <= 2; i++)
+for (int i = 0; i <= 2; i++)
{
if (fstat(i, &statbuf) < 0 && errno == EBADF)
{
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"));
+ string_open_failed(errno, "/dev/null", NULL));
if (devnull != i) (void)dup2(devnull, i);
}
}
{
if (smtp_input)
{
-#ifdef SUPPORT_TLS
+#ifndef DISABLE_TLS
tls_close(NULL, TLS_NO_SHUTDOWN); /* Shut down the TLS library */
#endif
(void)close(fileno(smtp_in));
save_errno = errno;
debug_printf(" auxiliary group list:");
if (group_count > 0)
- {
- int i;
- for (i = 0; i < group_count; i++) debug_printf(" %d", (int)group_list[i]);
- }
+ for (int i = 0; i < group_count; i++) debug_printf(" %d", (int)group_list[i]);
else if (group_count < 0)
debug_printf(" <error: %s>", strerror(save_errno));
else debug_printf(" <none>");
exim_exit(int rc, const uschar * process)
{
search_tidyup();
+store_exit();
DEBUG(D_any)
debug_printf(">>>>>>>>>>>>>>>> Exim pid=%d %s%s%sterminating with rc=%d "
">>>>>>>>>>>>>>>>\n", (int)getpid(),
}
+void
+exim_underbar_exit(int rc)
+{
+store_exit();
+_exit(rc);
+}
+
+
/* Print error string, then die */
static void
exit(EXIT_FAILURE);
}
+/* exim_chown_failure() called from exim_chown()/exim_fchown() on failure
+of chown()/fchown(). See src/functions.h for more explanation */
+int
+exim_chown_failure(int fd, const uschar *name, uid_t owner, gid_t group)
+{
+int saved_errno = errno; /* from the preceeding chown call */
+#if 1
+log_write(0, LOG_MAIN|LOG_PANIC,
+ __FILE__ ":%d: chown(%s, %d:%d) failed (%s)."
+ " Please contact the authors and refer to https://bugs.exim.org/show_bug.cgi?id=2391",
+ __LINE__, name?name:US"<unknown>", owner, group, strerror(errno));
+#else
+/* I leave this here, commented, in case the "bug"(?) comes up again.
+ It is not an Exim bug, but we can provide a workaround.
+ See Bug 2391
+ HS 2019-04-18 */
+
+struct stat buf;
+
+if (0 == (fd < 0 ? stat(name, &buf) : fstat(fd, &buf)))
+{
+ if (buf.st_uid == owner && buf.st_gid == group) return 0;
+ log_write(0, LOG_MAIN|LOG_PANIC, "Wrong ownership on %s", name);
+}
+else log_write(0, LOG_MAIN|LOG_PANIC, "Stat failed on %s: %s", name, strerror(errno));
+
+#endif
+errno = saved_errno;
+return -1;
+}
/*************************************************
static void
show_whats_supported(FILE * fp)
{
-auth_info * authi;
-
DEBUG(D_any) {} else show_db_version(fp);
fprintf(fp, "Support for:");
#ifdef USE_TCP_WRAPPERS
fprintf(fp, " TCPwrappers");
#endif
-#ifdef SUPPORT_TLS
-# ifdef USE_GNUTLS
+#ifdef USE_GNUTLS
fprintf(fp, " GnuTLS");
-# else
+#endif
+#ifdef USE_OPENSSL
fprintf(fp, " OpenSSL");
-# endif
#endif
#ifdef SUPPORT_TRANSLATE_IP_ADDRESS
fprintf(fp, " translate_ip_address");
#ifndef DISABLE_OCSP
fprintf(fp, " OCSP");
#endif
+#ifdef SUPPORT_PIPE_CONNECT
+ fprintf(fp, " PIPE_CONNECT");
+#endif
#ifndef DISABLE_PRDR
fprintf(fp, " PRDR");
#endif
#ifdef SUPPORT_SPF
fprintf(fp, " SPF");
#endif
+#ifdef SUPPORT_DMARC
+ fprintf(fp, " DMARC");
+#endif
#ifdef TCP_FASTOPEN
deliver_init();
if (f.tcp_fastopen_ok) fprintf(fp, " TCP_Fast_Open");
#ifdef EXPERIMENTAL_DCC
fprintf(fp, " Experimental_DCC");
#endif
-#ifdef EXPERIMENTAL_DMARC
- fprintf(fp, " Experimental_DMARC");
-#endif
#ifdef EXPERIMENTAL_DSN_INFO
fprintf(fp, " Experimental_DSN_info");
#endif
-#ifdef EXPERIMENTAL_REQUIRETLS
- fprintf(fp, " Experimental_REQUIRETLS");
-#endif
-#ifdef EXPERIMENTAL_PIPE_CONNECT
- fprintf(fp, " Experimental_PIPE_CONNECT");
+#ifdef EXPERIMENTAL_TLS_RESUME
+ fprintf(fp, " Experimental_TLS_resume");
#endif
fprintf(fp, "\n");
#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
fprintf(fp, " ibase");
#endif
+#if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
+ fprintf(fp, " json");
+#endif
#if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
fprintf(fp, " ldap ldapdn ldapm");
#endif
Perhaps the tls_version_report should move into this too. */
DEBUG(D_any) do {
- int i;
-
/* clang defines __GNUC__ (at least, for me) so test for it first */
#if defined(__clang__)
fprintf(fp, "Compiler: CLang [%s]\n", __clang_version__);
show_db_version(fp);
-#ifdef SUPPORT_TLS
+#ifndef DISABLE_TLS
tls_version_report(fp);
#endif
#ifdef SUPPORT_I18N
utf8_version_report(fp);
#endif
- for (authi = auths_available; *authi->driver_name != '\0'; ++authi)
+ for (auth_info * authi = auths_available; *authi->driver_name != '\0'; ++authi)
if (authi->version_report)
(*authi->version_report)(fp);
#undef EXPAND_AND_QUOTE
init_lookup_list();
- for (i = 0; i < lookup_list_count; i++)
+ for (int i = 0; i < lookup_list_count; i++)
if (lookup_list[i]->version_report)
lookup_list[i]->version_report(fp);
static void
show_exim_information(enum commandline_info request, FILE *stream)
{
-const uschar **pp;
-
switch(request)
{
case CMDINFO_NONE:
);
return;
case CMDINFO_SIEVE:
- for (pp = exim_sieve_extension_list; *pp; ++pp)
+ for (const uschar ** pp = exim_sieve_extension_list; *pp; ++pp)
fprintf(stream, "%s\n", *pp);
return;
case CMDINFO_DSCP:
{
BOOL needs_quote = FALSE;
gstring * g;
-uschar *t;
-for (t = lpart; !needs_quote && *t != 0; t++)
+for (uschar * t = lpart; !needs_quote && *t != 0; t++)
{
needs_quote = !isalnum(*t) && strchr("!#$%&'*+-/=?^_`{|}~", *t) == NULL &&
(*t != '.' || t == lpart || t[1] == 0);
static uschar *
get_stdinput(char *(*fn_readline)(const char *), void(*fn_addhist)(const char *))
{
-int i;
gstring * g = NULL;
if (!fn_readline) { printf("> "); fflush(stdout); }
-for (i = 0;; i++)
+for (int i = 0;; i++)
{
uschar buffer[1024];
uschar *p, *ss;
#ifdef USE_READLINE
char *readline_line = NULL;
- if (fn_readline != NULL)
+ if (fn_readline)
{
- if ((readline_line = fn_readline((i > 0)? "":"> ")) == NULL) break;
- if (*readline_line != 0 && fn_addhist != NULL) fn_addhist(readline_line);
+ if (!(readline_line = fn_readline((i > 0)? "":"> "))) break;
+ if (*readline_line != 0 && fn_addhist) fn_addhist(readline_line);
p = US readline_line;
}
else
while (ss > p && isspace(ss[-1])) ss--;
if (i > 0)
- {
while (p < ss && isspace(*p)) p++; /* leading space after cont */
- }
g = string_catn(g, p, ss - p);
macros_trusted(BOOL opt_D_used)
{
#ifdef WHITELIST_D_MACROS
-macro_item *m;
-uschar *whitelisted, *end, *p, **whites, **w;
+uschar *whitelisted, *end, *p, **whites;
int white_count, i, n;
size_t len;
BOOL prev_char_item, found;
}
/* Get a list of macros which are whitelisted */
-whitelisted = string_copy_malloc(US WHITELIST_D_MACROS);
+whitelisted = string_copy_perm(US WHITELIST_D_MACROS, FALSE);
prev_char_item = FALSE;
white_count = 0;
for (p = whitelisted; *p != '\0'; ++p)
/* The list of commandline macros should be very short.
Accept the N*M complexity. */
-for (m = macros_user; m; m = m->next) if (m->command_line)
+for (macro_item * m = macros_user; m; m = m->next) if (m->command_line)
{
found = FALSE;
- for (w = whites; *w; ++w)
+ for (uschar ** w = whites; *w; ++w)
if (Ustrcmp(*w, m->name) == 0)
{
found = TRUE;
uschar *real_sender_address;
uschar *originator_home = US"/";
size_t sz;
-void *reset_point;
+rmark reset_point;
struct passwd *pw;
struct stat statbuf;
/* Set up the handler for the data request signal, and set the initial
descriptive text. */
+process_info = store_get(PROCESS_INFO_SIZE, TRUE); /* tainted */
set_process_info("initializing");
os_restarting_signal(SIGUSR1, usr1_handler);
else
{
/* Well, the trust list at least is up to scratch... */
- void *reset_point = store_get(0);
+ rmark reset_point = store_mark();
uschar *trusted_configs[32];
int nr_configs = 0;
int i = 0;
&sep, big_buffer, big_buffer_size)) != NULL)
{
for (i=0; i < nr_configs; i++)
- {
if (Ustrcmp(filename, trusted_configs[i]) == 0)
break;
- }
if (i == nr_configs)
{
f.trusted_config = FALSE;
break;
}
}
- store_reset(reset_point);
}
- else
- {
- /* No valid prefixes found in trust_list file. */
+ else /* No valid prefixes found in trust_list file. */
f.trusted_config = FALSE;
- }
+ store_reset(reset_point);
}
}
- else
- {
- /* Could not open trust_list file. */
+ else /* Could not open trust_list file. */
f.trusted_config = FALSE;
- }
}
#else
/* Not root; don't trust config */
if (clmacro_count >= MAX_CLMACROS)
exim_fail("exim: too many -D options on command line\n");
- clmacros[clmacro_count++] = string_sprintf("-D%s=%s", m->name,
- m->replacement);
+ clmacros[clmacro_count++] =
+ string_sprintf("-D%s=%s", m->name, m->replacement);
}
#endif
break;
{ badarg = TRUE; break; }
}
if (*argrest == 0)
- sender_address = string_sprintf(""); /* Ensure writeable memory */
+ *(sender_address = store_get(1, FALSE)) = '\0'; /* Ensure writeable memory */
else
{
uschar *temp = argrest + Ustrlen(argrest) - 1;
#endif
sender_address = parse_extract_address(argrest, &errmess,
&dummy_start, &dummy_end, &sender_address_domain, TRUE);
+ sender_address = string_copy_taint(sender_address, TRUE);
#ifdef SUPPORT_I18N
message_smtputf8 = string_is_utf8(sender_address);
allow_utf8_domains = FALSE;
case 'S': smtp_peer_options |= OPTION_SIZE; break;
-#ifdef SUPPORT_TLS
+#ifndef DISABLE_TLS
/* -MCt: similar to -MCT below but the connection is still open
- via a proxy proces which handles the TLS context and coding.
+ via a proxy process which handles the TLS context and coding.
Require three arguments for the proxied local address and port,
and the TLS cipher. */
break;
}
-#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_REQUIRETLS)
- /* -MS set REQUIRETLS on (new) message */
-
- else if (*argrest == 'S')
- {
- tls_requiretls |= REQUIRETLS_MSG;
- break;
- }
-#endif
-
/* -M[x]: various operations on the following list of message ids:
-M deliver the messages, ignoring next retry times and thawing
-Mc deliver the messages, checking next retry times, no thawing
if (!one_msg_action)
{
- int j;
- for (j = msg_action_arg; j < argc; j++) if (!mac_ismsgid(argv[j]))
+ for (int j = msg_action_arg; j < argc; j++) if (!mac_ismsgid(argv[j]))
exim_fail("exim: malformed message id %s after %s option\n",
argv[j], arg);
goto END_ARG; /* Remaining args are ids */
/* -oMas: setting authenticated sender */
- else if (Ustrcmp(argrest, "Mas") == 0) authenticated_sender = argv[++i];
+ else if (Ustrcmp(argrest, "Mas") == 0)
+ authenticated_sender = string_copy_taint(argv[++i], TRUE);
/* -oMai: setting authenticated id */
- else if (Ustrcmp(argrest, "Mai") == 0) authenticated_id = argv[++i];
+ else if (Ustrcmp(argrest, "Mai") == 0)
+ authenticated_id = string_copy_taint(argv[++i], TRUE);
/* -oMi: Set incoming interface address */
/* -oMs: Set sender host name */
- else if (Ustrcmp(argrest, "Ms") == 0) sender_host_name = argv[++i];
+ else if (Ustrcmp(argrest, "Ms") == 0)
+ sender_host_name = string_copy_taint(argv[++i], TRUE);
/* -oMt: Set sender ident */
/* -q[f][f][l][G<name>]: Run the queue, optionally forced, optionally local
only, optionally named, optionally starting from a given message id. */
- if (*argrest == 0 &&
- (i + 1 >= argc || argv[i+1][0] == '-' || mac_ismsgid(argv[i+1])))
- {
- queue_interval = 0;
- if (i+1 < argc && mac_ismsgid(argv[i+1]))
- start_queue_run_id = argv[++i];
- if (i+1 < argc && mac_ismsgid(argv[i+1]))
- stop_queue_run_id = argv[++i];
- }
+ if (!(list_queue || count_queue))
+ if (*argrest == 0
+ && (i + 1 >= argc || argv[i+1][0] == '-' || mac_ismsgid(argv[i+1])))
+ {
+ queue_interval = 0;
+ if (i+1 < argc && mac_ismsgid(argv[i+1]))
+ start_queue_run_id = argv[++i];
+ if (i+1 < argc && mac_ismsgid(argv[i+1]))
+ stop_queue_run_id = argv[++i];
+ }
/* -q[f][f][l][G<name>/]<n>: Run the queue at regular intervals, optionally
forced, optionally local only, optionally named. */
- else if ((queue_interval = readconf_readtime(*argrest ? argrest : argv[++i],
- 0, FALSE)) <= 0)
- exim_fail("exim: bad time value %s: abandoned\n", argv[i]);
+ else if ((queue_interval = readconf_readtime(*argrest ? argrest : argv[++i],
+ 0, FALSE)) <= 0)
+ exim_fail("exim: bad time value %s: abandoned\n", argv[i]);
break;
argument. */
if (*argrest != 0)
- {
- int i;
- for (i = 0; i < nelem(rsopts); i++)
+ for (int i = 0; i < nelem(rsopts); i++)
if (Ustrcmp(argrest, rsopts[i]) == 0)
{
if (i != 2) f.queue_run_force = TRUE;
if (i == 1 || i == 4) f.deliver_force_thaw = TRUE;
argrest += Ustrlen(rsopts[i]);
}
- }
/* -R: Set string to match in addresses for forced queue run to
pick out particular messages. */
argument. */
if (*argrest)
- {
- int i;
- for (i = 0; i < nelem(rsopts); i++)
+ for (int i = 0; i < nelem(rsopts); i++)
if (Ustrcmp(argrest, rsopts[i]) == 0)
{
if (i != 2) f.queue_run_force = TRUE;
if (i == 1 || i == 4) f.deliver_force_thaw = TRUE;
argrest += Ustrlen(rsopts[i]);
}
- }
/* -S: Set string to match in addresses for forced queue run to
pick out particular messages. */
/* -tls-on-connect: don't wait for STARTTLS (for old clients) */
- #ifdef SUPPORT_TLS
+ #ifndef DISABLE_TLS
else if (Ustrcmp(argrest, "ls-on-connect") == 0) tls_in.on_connect = TRUE;
#endif
is a failure. It leaves the configuration file open so that the subsequent
configuration data for delivery can be read if needed.
-NOTE: immediatly after opening the configuration file we change the working
+NOTE: immediately after opening the configuration file we change the working
directory to "/"! Later we change to $spool_directory. We do it there, because
during readconf_main() some expansion takes place already. */
if (real_uid == root_uid || real_uid == exim_uid || real_gid == exim_gid)
f.admin_user = TRUE;
else
- {
- int i, j;
- for (i = 0; i < group_count && !f.admin_user; i++)
+ for (int i = 0; i < group_count && !f.admin_user; i++)
if (group_list[i] == exim_gid)
f.admin_user = TRUE;
else if (admin_groups)
- for (j = 1; j <= (int)admin_groups[0] && !f.admin_user; j++)
+ for (int j = 1; j <= (int)admin_groups[0] && !f.admin_user; j++)
if (admin_groups[j] == group_list[i])
f.admin_user = TRUE;
- }
/* Another group of privileged users are the trusted users. These are root,
exim, and any caller matching trusted_users or trusted_groups. Trusted callers
f.trusted_caller = TRUE;
else
{
- int i, j;
-
if (trusted_users)
- for (i = 1; i <= (int)trusted_users[0] && !f.trusted_caller; i++)
+ for (int i = 1; i <= (int)trusted_users[0] && !f.trusted_caller; i++)
if (trusted_users[i] == real_uid)
f.trusted_caller = TRUE;
if (trusted_groups)
- for (i = 1; i <= (int)trusted_groups[0] && !f.trusted_caller; i++)
+ for (int i = 1; i <= (int)trusted_groups[0] && !f.trusted_caller; i++)
if (trusted_groups[i] == real_gid)
f.trusted_caller = TRUE;
- else for (j = 0; j < group_count && !f.trusted_caller; j++)
+ else for (int j = 0; j < group_count && !f.trusted_caller; j++)
if (trusted_groups[i] == group_list[j])
f.trusted_caller = TRUE;
}
DEBUG(D_any)
{
- int i;
debug_printf("configuration file is %s\n", config_main_filename);
debug_printf("log selectors =");
- for (i = 0; i < log_selector_size; i++)
+ for (int i = 0; i < log_selector_size; i++)
debug_printf(" %08x", log_selector[i]);
debug_printf("\n");
}
*/
#ifdef EXIM_TMPDIR
- {
- uschar **p;
- if (environ) for (p = USS environ; *p; p++)
+ if (environ) for (uschar ** p = USS environ; *p; p++)
if (Ustrncmp(*p, "TMPDIR=", 7) == 0 && Ustrcmp(*p+7, EXIM_TMPDIR) != 0)
{
uschar * newp = store_malloc(Ustrlen(EXIM_TMPDIR) + 8);
*p = newp;
DEBUG(D_any) debug_printf("reset TMPDIR=%s in environment\n", EXIM_TMPDIR);
}
- }
#endif
/* Timezone handling. If timezone_string is "utc", set a flag to cause all
if ( (debug_selector & D_any || LOGGING(arguments))
&& f.really_exim && !list_options && !checking)
{
- int i;
uschar *p = big_buffer;
- Ustrcpy(p, "cwd= (failed)");
+ Ustrcpy(p, US"cwd= (failed)");
if (!initial_cwd)
p += 13;
(void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc);
while (*p) p++;
- for (i = 0; i < argc; i++)
+ for (int i = 0; i < argc; i++)
{
int len = Ustrlen(argv[i]);
const uschar *printing;
uschar *quote;
if (p + len + 8 >= big_buffer + big_buffer_size)
{
- Ustrcpy(p, " ...");
+ Ustrcpy(p, US" ...");
log_write(0, LOG_MAIN, "%s", big_buffer);
- Ustrcpy(big_buffer, "...");
+ Ustrcpy(big_buffer, US"...");
p = big_buffer + 3;
}
printing = string_printing(argv[i]);
else
{
int rv;
+ DEBUG(D_any) debug_printf("dropping to exim gid; retaining priv uid\n");
rv = setgid(exim_gid);
/* Impact of failure is that some stuff might end up with an incorrect group.
We track this for failures from root, since any attempt to change privilege
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,
-this is just a bit of pedantic tidiness. It wouldn't really matter if the
-configuration were read into POOL_MAIN, because we don't do any resets till
-later on. However, it seems right, and it does ensure that both pools get used.
-*/
-
-store_pool = POOL_MAIN;
-
/* Handle the -brt option. This is for checking out retry configurations.
The next three arguments are a domain name or a complete address, and
optionally two error numbers. All it does is to call the function that
printf("No retry information found\n");
else
{
- retry_rule *r;
more_errno = yield->more_errno;
printf("Retry rule: %s ", yield->pattern);
printf("auth_failed ");
else printf("* ");
- for (r = yield->rules; r; r = r->next)
+ for (retry_rule * r = yield->rules; r; r = r->next)
{
printf("%c,%s", r->rule, readconf_printtime(r->timeout)); /* Do not */
printf(",%s", readconf_printtime(r->p1)); /* amalgamate */
else if ((pid = fork()) == 0)
{
(void)deliver_message(argv[i], forced_delivery, deliver_give_up);
- _exit(EXIT_SUCCESS);
+ exim_underbar_exit(EXIT_SUCCESS);
}
else if (pid < 0)
{
the caller. This will get overwritten below for an inetd call. If a trusted
caller has set it empty, unset it. */
-if (sender_ident == NULL) sender_ident = originator_login;
- else if (sender_ident[0] == 0) sender_ident = NULL;
+if (!sender_ident) sender_ident = originator_login;
+else if (!*sender_ident) sender_ident = NULL;
/* Handle the -brw option, which is for checking out rewriting rules. Cause log
writes (on errors) to go to stderr instead. Can't do this earlier, as want the
unless a trusted caller supplies a sender address with -f, or is passing in the
message via SMTP (inetd invocation or otherwise). */
-if ((sender_address == NULL && !smtp_input) ||
- (!f.trusted_caller && filter_test == FTEST_NONE))
+if ( !sender_address && !smtp_input
+ || !f.trusted_caller && filter_test == FTEST_NONE)
{
f.sender_local = TRUE;
via -oMas and -oMai and if so, they will already be set. Otherwise, force
defaults except when host checking. */
- if (authenticated_sender == NULL && !host_checking)
+ if (!authenticated_sender && !host_checking)
authenticated_sender = string_sprintf("%s@%s", originator_login,
qualify_domain_sender);
- if (authenticated_id == NULL && !host_checking)
+ if (!authenticated_id && !host_checking)
authenticated_id = originator_login;
}
specify a sender address for SMTP input, we leave sender_address unset. This
causes the MAIL commands to be honoured. */
-if ((!smtp_input && sender_address == NULL) ||
- !receive_check_set_sender(sender_address))
+if ( !smtp_input && !sender_address
+ || !receive_check_set_sender(sender_address))
{
/* Either the caller is not permitted to set a general sender, or this is
non-SMTP input and the trusted caller has not set a sender. If there is no
address, which indicates an error message, or doesn't exist (root caller, smtp
interface, no -f argument). */
-if (sender_address != NULL && sender_address[0] != 0 &&
- sender_address_domain == 0)
+if (sender_address && *sender_address && sender_address_domain == 0)
sender_address = string_sprintf("%s@%s", local_part_quote(sender_address),
qualify_domain_sender);
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 */
+ sender_host_address = store_get(48, FALSE); /* large enough for full IPv6 */
(void)host_nmtoa(size, x, -1, sender_host_address, ':');
/* Now set up for testing */
if (smtp_start_session())
{
- for (reset_point = store_get(0); ; store_reset(reset_point))
+ for (; (reset_point = store_mark()); store_reset(reset_point))
{
if (smtp_setup_msg() <= 0) break;
if (!receive_msg(FALSE)) break;
/* Save the current store pool point, for resetting at the start of
each message, and save the real sender address, if any. */
-reset_point = store_get(0);
real_sender_address = sender_address;
/* Loop to receive messages; receive_msg() returns TRUE if there are more
while (more)
{
+ reset_point = store_mark();
message_id[0] = 0;
/* Handle the SMTP case; call smtp_setup_mst() to deal with the initial SMTP
else
{
- int i;
int rcount = 0;
int count = argc - recipients_arg;
uschar **list = argv + recipients_arg;
/* Loop for each argument */
- for (i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
{
int start, end, domain;
uschar *errmess;
}
}
- receive_add_recipient(recipient, -1);
+ receive_add_recipient(string_copy_taint(recipient, TRUE), -1);
s = ss;
if (!finished)
while (*(++s) != 0 && (*s == ',' || isspace(*s)));
DEBUG(D_receive)
{
- int i;
if (sender_address != NULL) debug_printf("Sender: %s\n", sender_address);
if (recipients_list != NULL)
{
debug_printf("Recipients:\n");
- for (i = 0; i < recipients_count; i++)
+ for (int i = 0; i < recipients_count; i++)
debug_printf(" %s\n", recipients_list[i].address);
}
}
rc = deliver_message(message_id, FALSE, FALSE);
search_tidyup();
- _exit((!mua_wrapper || rc == DELIVER_MUA_SUCCEEDED)?
- EXIT_SUCCESS : EXIT_FAILURE);
+ exim_underbar_exit(!mua_wrapper || rc == DELIVER_MUA_SUCCEEDED
+ ? EXIT_SUCCESS : EXIT_FAILURE);
}
if (pid < 0)
callout_address = NULL;
sending_ip_address = NULL;
acl_var_m = NULL;
- { int i; for(i=0; i<REGEX_VARS; i++) regex_vars[i] = NULL; }
+ for(int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
store_reset(reset_point);
}