* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2015 */
+/* Copyright (c) University of Cambridge 1995 - 2016 */
/* See the file NOTICE for conditions of use and distribution. */
/* The main code for delivering a message. */
if (fd < 0 && errno == ENOENT)
{
- uschar temp[16];
- sprintf(CS temp, "msglog/%s", message_subdir);
- if (message_subdir[0] == 0) temp[6] = 0;
+ uschar * temp = string_sprintf("msglog%s%s%s%s",
+ *queue_name ? "/" : "", queue_name,
+ *message_subdir ? "/" : "", message_subdir);
(void)directory_make(spool_directory, temp, MSGLOG_DIRECTORY_MODE, TRUE);
fd = Uopen(filename, O_WRONLY|O_APPEND|O_CREAT, mode);
}
s = LOGGING(outgoing_port)
? string_append(s, sizep, ptrp, 2, US"]:",
string_sprintf("%d", sending_port))
- : string_cat(s, sizep, ptrp, "]", 1);
+ : string_catn(s, sizep, ptrp, US"]", 1);
}
return s;
}
if (LOGGING(outgoing_port))
s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
addr->host_used->port));
+
+#ifdef SUPPORT_SOCKS
+if (LOGGING(proxy) && proxy_local_address)
+ {
+ s = string_append(s, sizep, ptrp, 3, US" PRX=[", proxy_local_address, US"]");
+ if (LOGGING(outgoing_port))
+ s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
+ proxy_local_port));
+ }
+#endif
+
return d_log_interface(s, sizep, ptrp);
}
+
+
#ifdef SUPPORT_TLS
static uschar *
d_tlslog(uschar * s, int * sizep, int * ptrp, address_item * addr)
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
uschar *
event_raise(uschar * action, const uschar * event, uschar * ev_data)
{
deliver_domain = save_domain;
router_name = transport_name = NULL;
}
-#endif /*EXPERIMENTAL_EVENT*/
+#endif /*DISABLE_EVENT*/
have a pointer to the host item that succeeded; local deliveries can have a
pointer to a single host item in their host list, for use by the transport. */
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
/* presume no successful remote delivery */
lookup_dnssec_authenticated = NULL;
#endif
if (LOGGING(sender_on_delivery) || msg)
s = string_append(s, &size, &ptr, 3, US" F=<",
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
testflag(addr, af_utf8_downcvt)
? string_address_utf8_to_alabel(sender_address, NULL)
:
sender_address,
US">");
+if (*queue_name)
+ s = string_append(s, &size, &ptr, 2, US" Q=", queue_name);
+
#ifdef EXPERIMENTAL_SRS
if(addr->prop.srs_sender)
s = string_append(s, &size, &ptr, 3, US" SRS=<", addr->prop.srs_sender, US">");
s = string_append(s, &size, &ptr, 2, US" H=", addr->host_list->name);
s = d_log_interface(s, &size, &ptr);
if (addr->shadow_message)
- s = string_cat(s, &size, &ptr, addr->shadow_message,
- Ustrlen(addr->shadow_message));
+ s = string_cat(s, &size, &ptr, addr->shadow_message);
}
/* Remote delivery */
{
s = d_hostlog(s, &size, &ptr, addr);
if (continue_sequence > 1)
- s = string_cat(s, &size, &ptr, US"*", 1);
+ s = string_catn(s, &size, &ptr, US"*", 1);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
deliver_host_address = addr->host_used->address;
deliver_host_port = addr->host_used->port;
deliver_host = addr->host_used->name;
s[ptr] = 0;
log_write(0, flags, "%s", s);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (!msg) msg_event_raise(US"msg:delivery", addr);
#endif
if (addr->message)
{
const uschar * s = string_printing(addr->message);
- if (s != addr->message)
- addr->message = US s;
- /* deconst cast ok as string_printing known to have alloc'n'copied */
- if ( ( Ustrstr(s, "failed to expand") != NULL
- || Ustrstr(s, "expansion of ") != NULL
- )
- && ( Ustrstr(s, "mysql") != NULL
- || Ustrstr(s, "pgsql") != NULL
-#ifdef EXPERIMENTAL_REDIS
- || Ustrstr(s, "redis") != NULL
-#endif
- || Ustrstr(s, "sqlite") != NULL
- || Ustrstr(s, "ldap:") != NULL
- || Ustrstr(s, "ldapdn:") != NULL
- || Ustrstr(s, "ldapm:") != NULL
- ) )
- addr->message = string_sprintf("Temporary internal error");
+
+ /* deconst cast ok as string_printing known to have alloc'n'copied */
+ addr->message = expand_hide_passwords(US s);
}
/* If we used a transport that has one of the "return_output" options set, and
log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
- s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address));
+ s = string_cat(s, &size, &ptr, log_address);
+
+ if (*queue_name)
+ s = string_append(s, &size, &ptr, 2, US" Q=", queue_name);
/* Either driver_name contains something and driver_kind contains
" router" or " transport" (note the leading space), or driver_name is
s = string_append(s, &size, &ptr, 2, US" ", driver_kind);
sprintf(CS ss, " defer (%d)", addr->basic_errno);
- s = string_cat(s, &size, &ptr, ss, Ustrlen(ss));
+ s = string_cat(s, &size, &ptr, ss);
if (addr->basic_errno > 0)
s = string_append(s, &size, &ptr, 2, US": ",
log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
- s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address));
+ s = string_cat(s, &size, &ptr, log_address);
if (LOGGING(sender_on_delivery))
s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
+ if (*queue_name)
+ s = string_append(s, &size, &ptr, 2, US" Q=", queue_name);
+
/* Return path may not be set if no delivery actually happened */
if (used_return_path && LOGGING(return_path_on_delivery))
log_write(0, LOG_MAIN, "** %s", s);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
msg_event_raise(US"msg:fail:delivery", addr);
#endif
{
uschar *error;
addr->return_filename =
- string_sprintf("%s/msglog/%s/%s-%d-%d", spool_directory, message_subdir,
+ string_sprintf("%s/msglog/%s/%s/%s-%d-%d",
+ spool_directory, queue_name, message_subdir,
message_id, getpid(), return_count++);
addr->return_file = open_msglog_file(addr->return_filename, 0400, &error);
if (addr->return_file < 0)
if (message_length > 0)
{
len = read(pfd[pipe_read], big_buffer, message_length);
+ big_buffer[big_buffer_size-1] = '\0'; /* guard byte */
if (len > 0) *sptr = string_copy(big_buffer);
}
}
switch (subid)
{
+#ifdef SUPPORT_SOCKS
+ case '2': /* proxy information; must arrive before A0 and applies to that addr XXX oops*/
+ proxy_session = TRUE; /*XXX shouod this be cleared somewhere? */
+ if (*ptr == 0)
+ ptr++;
+ else
+ {
+ proxy_local_address = string_copy(ptr);
+ while(*ptr++);
+ memcpy(&proxy_local_port, ptr, sizeof(proxy_local_port));
+ ptr += sizeof(proxy_local_port);
+ }
+ break;
+#endif
+
#ifdef EXPERIMENTAL_DSN_INFO
case '1': /* must arrive before A0, and applies to that addr */
/* Two strings: smtp_greeting and helo_response */
rmt_dlv_checked_write(int fd, char id, char subid, void * buf, int size)
{
uschar writebuffer[PIPE_HEADER_SIZE + BIG_BUFFER_SIZE];
-int header_length;
+int header_length;
+int ret;
/* we assume that size can't get larger then BIG_BUFFER_SIZE which currently is set to 16k */
/* complain to log if someone tries with buffer sizes we can't handle*/
memcpy(writebuffer + PIPE_HEADER_SIZE, buf, size);
size += PIPE_HEADER_SIZE;
-int ret = write(fd, writebuffer, size);
-if(ret != size)
+if ((ret = write(fd, writebuffer, size)) != size)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed writing transport result to pipe: %s\n",
ret == -1 ? strerror(errno) : "short write");
}
addr_fallback = addr;
}
- else
+ else if (next)
{
while (next->next) next = next->next;
next->next = addr_defer;
a dup-with-new-file-pointer. */
(void)close(deliver_datafile);
- sprintf(CS spoolname, "%s/input/%s/%s-D", spool_directory, message_subdir,
- message_id);
- deliver_datafile = Uopen(spoolname, O_RDWR | O_APPEND, 0);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-D",
+ spool_directory, queue_name, message_subdir, message_id);
- if (deliver_datafile < 0)
+ if ((deliver_datafile = Uopen(spoolname, O_RDWR | O_APPEND, 0)) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to reopen %s for remote "
"parallel delivery: %s", spoolname, strerror(errno));
#ifdef SUPPORT_TLS
if (addr->cipher)
{
- ptr = big_buffer;
- sprintf(CS ptr, "%.128s", addr->cipher);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", addr->cipher) + 1;
if (!addr->peerdn)
*ptr++ = 0;
else
{
- sprintf(CS ptr, "%.512s", addr->peerdn);
- while(*ptr++);
+ ptr += sprintf(CS ptr, "%.512s", addr->peerdn);
+ ptr++;
}
rmt_dlv_checked_write(fd, 'X', '1', big_buffer, ptr - big_buffer);
# ifndef DISABLE_OCSP
if (addr->ocsp > OCSP_NOT_REQ)
{
- ptr = big_buffer;
- sprintf(CS ptr, "%c", addr->ocsp + '0');
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%c", addr->ocsp + '0') + 1;
rmt_dlv_checked_write(fd, 'X', '4', big_buffer, ptr - big_buffer);
}
# endif
if (client_authenticator)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticator);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticator) + 1;
rmt_dlv_checked_write(fd, 'C', '1', big_buffer, ptr - big_buffer);
}
if (client_authenticated_id)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticated_id);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticated_id) + 1;
rmt_dlv_checked_write(fd, 'C', '2', big_buffer, ptr - big_buffer);
}
if (client_authenticated_sender)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticated_sender);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticated_sender) + 1;
rmt_dlv_checked_write(fd, 'C', '3', big_buffer, ptr - big_buffer);
}
rmt_dlv_checked_write(fd, 'R', '0', big_buffer, ptr - big_buffer);
}
+#ifdef SUPPORT_SOCKS
+ if (LOGGING(proxy) && proxy_session)
+ {
+ ptr = big_buffer;
+ if (proxy_local_address)
+ {
+ DEBUG(D_deliver) debug_printf("proxy_local_address '%s'\n", proxy_local_address);
+ ptr = big_buffer + sprintf(CS ptr, "%.128s", proxy_local_address) + 1;
+ DEBUG(D_deliver) debug_printf("proxy_local_port %d\n", proxy_local_port);
+ memcpy(ptr, &proxy_local_port, sizeof(proxy_local_port));
+ ptr += sizeof(proxy_local_port);
+ }
+ else
+ *ptr++ = '\0';
+ rmt_dlv_checked_write(fd, 'A', '2', big_buffer, ptr - big_buffer);
+ }
+#endif
+
#ifdef EXPERIMENTAL_DSN_INFO
/*um, are they really per-addr? Other per-conn stuff is not (auth, tls). But host_used is! */
if (addr->smtp_greeting)
{
- ptr = big_buffer;
DEBUG(D_deliver) debug_printf("smtp_greeting '%s'\n", addr->smtp_greeting);
- sprintf(CS ptr, "%.128s", addr->smtp_greeting);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", addr->smtp_greeting) + 1;
if (addr->helo_response)
{
DEBUG(D_deliver) debug_printf("helo_response '%s'\n", addr->helo_response);
- sprintf(CS ptr, "%.128s", addr->helo_response);
- while(*ptr++);
+ ptr += sprintf(CS ptr, "%.128s", addr->helo_response) + 1;
}
else
*ptr++ = '\0';
/* The rest of the information goes in an 'A0' item. */
- sprintf(CS big_buffer, "%c%c", addr->transport_return,
- addr->special_action);
+ sprintf(CS big_buffer, "%c%c", addr->transport_return, addr->special_action);
ptr = big_buffer + 2;
memcpy(ptr, &(addr->basic_errno), sizeof(addr->basic_errno));
ptr += sizeof(addr->basic_errno);
ptr += sizeof(addr->flags);
if (!addr->message) *ptr++ = 0; else
- {
- sprintf(CS ptr, "%.1024s", addr->message);
- while(*ptr++);
- }
+ ptr += sprintf(CS ptr, "%.1024s", addr->message) + 1;
if (!addr->user_message) *ptr++ = 0; else
- {
- sprintf(CS ptr, "%.1024s", addr->user_message);
- while(*ptr++);
- }
+ ptr += sprintf(CS ptr, "%.1024s", addr->user_message) + 1;
if (!addr->host_used) *ptr++ = 0; else
{
- sprintf(CS ptr, "%.256s", addr->host_used->name);
- while(*ptr++);
- sprintf(CS ptr, "%.64s", addr->host_used->address);
- while(*ptr++);
+ ptr += sprintf(CS ptr, "%.256s", addr->host_used->name) + 1;
+ ptr += sprintf(CS ptr, "%.64s", addr->host_used->address) + 1;
memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port));
ptr += sizeof(addr->host_used->port);
if (LOGGING(incoming_interface) && sending_ip_address)
#endif
{
- uschar * ptr = big_buffer;
- sprintf(CS ptr, "%.128s", sending_ip_address);
- while(*ptr++);
- sprintf(CS ptr, "%d", sending_port);
- while(*ptr++);
-
+ uschar * ptr;
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", sending_ip_address) + 1;
+ ptr += sprintf(CS ptr, "%d", sending_port) + 1;
rmt_dlv_checked_write(fd, 'I', '0', big_buffer, ptr - big_buffer);
}
para = store_get(size);
for (;;)
{
- para = string_cat(para, &size, &ptr, buffer, Ustrlen(buffer));
+ para = string_cat(para, &size, &ptr, buffer);
if (!Ufgets(buffer, sizeof(buffer), f) || Ustrcmp(buffer, "****\n") == 0)
break;
}
while queue running - another process probably completed delivery. As part of
opening the data file, message_subdir gets set. */
-if (!spool_open_datafile(id))
+if ((deliver_datafile = spool_open_datafile(id)) < 0)
return continue_closedown(); /* yields DELIVER_NOT_ATTEMPTED */
/* The value of message_size at this point has been set to the data length,
if (errno == ERRNO_SPOOLFORMAT)
{
struct stat statbuf;
- sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir,
- spoolname);
+ sprintf(CS big_buffer, "%s/input/%s/%s/%s",
+ spool_directory, queue_name, message_subdir, spoolname);
if (Ustat(big_buffer, &statbuf) == 0)
log_write(0, LOG_MAIN, "Format error in spool file %s: "
"size=" OFF_T_FMT, spoolname, statbuf.st_size);
if (now - received_time > keep_malformed)
{
- sprintf(CS spoolname, "%s/msglog/%s/%s", spool_directory, message_subdir, id);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/msglog/%s/%s/%s",
+ spool_directory, queue_name, message_subdir, id);
Uunlink(spoolname);
- sprintf(CS spoolname, "%s/input/%s/%s-D", spool_directory, message_subdir, id);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-D",
+ spool_directory, queue_name, message_subdir, id);
Uunlink(spoolname);
- sprintf(CS spoolname, "%s/input/%s/%s-H", spool_directory, message_subdir, id);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-H",
+ spool_directory, queue_name, message_subdir, id);
Uunlink(spoolname);
- sprintf(CS spoolname, "%s/input/%s/%s-J", spool_directory, message_subdir, id);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-J",
+ spool_directory, queue_name, message_subdir, id);
Uunlink(spoolname);
log_write(0, LOG_MAIN, "Message removed because older than %s",
readconf_printtime(keep_malformed));
run, and it will be deleted if this function gets to its end successfully.
Otherwise it might be needed again. */
-sprintf(CS spoolname, "%s/input/%s/%s-J", spool_directory, message_subdir, id);
-jread = Ufopen(spoolname, "rb");
-if (jread)
+snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-J",
+ spool_directory, queue_name, message_subdir, id);
+
+if ((jread = Ufopen(spoolname, "rb")))
{
while (Ufgets(big_buffer, big_buffer_size, jread))
{
uschar *error;
int fd;
- sprintf(CS spoolname, "%s/msglog/%s/%s", spool_directory, message_subdir, id);
- fd = open_msglog_file(spoolname, SPOOL_MODE, &error);
-
- if (fd < 0)
+ snprintf(CS spoolname, sizeof(spoolname), "%s/msglog/%s/%s/%s",
+ spool_directory, queue_name, message_subdir, id);
+
+ if ((fd = open_msglog_file(spoolname, SPOOL_MODE, &error)) < 0)
{
log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't %s message log %s: %s", error,
spoolname, strerror(errno));
recipient_item *r = recipients_list + i;
address_item *new = deliver_make_addr(r->address, FALSE);
new->prop.errors_address = r->errors_to;
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
if ((new->prop.utf8_msg = message_smtputf8))
{
new->prop.utf8_downcvt = message_utf8_downconvert == 1;
break;
}
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (process_recipients != RECIP_ACCEPT)
{
uschar * save_local = deliver_localpart;
if (addr_local || addr_remote)
{
- sprintf(CS spoolname, "%s/input/%s/%s-J", spool_directory, message_subdir, id);
- journal_fd = Uopen(spoolname, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE);
-
- if (journal_fd < 0)
+ snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-J",
+ spool_directory, queue_name, message_subdir, id);
+
+ if ((journal_fd = Uopen(spoolname, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE)) <0)
{
log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't open journal file %s: %s",
spoolname, strerror(errno));
else if (!dont_deliver)
retry_update(&addr_defer, &addr_failed, &addr_succeed);
-/* Send DSN for successful messages */
-addr_dsntmp = addr_succeed;
+/* Send DSN for successful messages if requested */
addr_senddsn = NULL;
-while(addr_dsntmp)
+for (addr_dsntmp = addr_succeed; addr_dsntmp; addr_dsntmp = addr_dsntmp->next)
{
/* af_ignore_error not honored here. it's not an error */
- DEBUG(D_deliver)
- {
- debug_printf("DSN: processing router : %s\n"
+ DEBUG(D_deliver) debug_printf("DSN: processing router : %s\n"
"DSN: processing successful delivery address: %s\n"
"DSN: Sender_address: %s\n"
"DSN: orcpt: %s flags: %d\n"
addr_dsntmp->address,
addr_dsntmp->dsn_aware
);
- }
/* send report if next hop not DSN aware or a router flagged "last DSN hop"
and a report was requested */
}
else
DEBUG(D_deliver) debug_printf("DSN: not sending DSN success message\n");
-
- addr_dsntmp = addr_dsntmp->next;
}
if (addr_senddsn)
if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0)
fprintf(f, "Original-Envelope-ID: %s\n", dsn_envid);
else
- fprintf(f, "X-Original-Envelope-ID: error decoding xtext formated ENVID\n");
+ fprintf(f, "X-Original-Envelope-ID: error decoding xtext formatted ENVID\n");
}
fputc('\n', f);
}
/* output machine readable part */
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
if (message_smtputf8)
fprintf(f, "--%s\n"
"Content-type: message/global-delivery-status\n\n"
if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0)
fprintf(f, "Original-Envelope-ID: %s\n", dsn_envid);
else
- fprintf(f, "X-Original-Envelope-ID: error decoding xtext formated ENVID\n");
+ fprintf(f, "X-Original-Envelope-ID: error decoding xtext formatted ENVID\n");
}
fputc('\n', f);
if (dsn_ret == dsn_ret_hdrs)
topt |= topt_no_body;
else
+ {
+ struct stat statbuf;
+
/* no full body return at all? */
if (!bounce_return_body)
{
if (dsn_ret == dsn_ret_full)
dsnnotifyhdr = dsnlimitmsg;
}
+ /* line length limited... return headers only if oversize */
/* size limited ... return headers only if limit reached */
- else if (bounce_return_size_limit > 0)
- {
- struct stat statbuf;
- if (fstat(deliver_datafile, &statbuf) == 0 && statbuf.st_size > max)
- {
- topt |= topt_no_body;
- dsnnotifyhdr = dsnlimitmsg;
- }
+ else if ( max_received_linelength > bounce_return_linesize_limit
+ || ( bounce_return_size_limit > 0
+ && fstat(deliver_datafile, &statbuf) == 0
+ && statbuf.st_size > max
+ ) )
+ {
+ topt |= topt_no_body;
+ dsnnotifyhdr = dsnlimitmsg;
}
+ }
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
if (message_smtputf8)
fputs(topt & topt_no_body ? "Content-type: message/global-headers\n\n"
: "Content-type: message/global\n\n",
{
if (message_logs)
{
- sprintf(CS spoolname, "%s/msglog/%s/%s", spool_directory, message_subdir,
- id);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/msglog/%s/%s/%s",
+ spool_directory, queue_name, message_subdir, id);
if (preserve_message_logs)
{
int rc;
- sprintf(CS big_buffer, "%s/msglog.OLD/%s", spool_directory, id);
+ sprintf(CS big_buffer, "%s/msglog.OLD/%s/%s",
+ spool_directory, queue_name, id);
if ((rc = Urename(spoolname, big_buffer)) < 0)
{
(void)directory_make(spool_directory, US"msglog.OLD",
/* Remove the two message files. */
- sprintf(CS spoolname, "%s/input/%s/%s-D", spool_directory, message_subdir, id);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-D",
+ spool_directory, queue_name, message_subdir, id);
if (Uunlink(spoolname) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
spoolname, strerror(errno));
- sprintf(CS spoolname, "%s/input/%s/%s-H", spool_directory, message_subdir, id);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-H",
+ spool_directory, queue_name, message_subdir, id);
if (Uunlink(spoolname) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
spoolname, strerror(errno));
/* Unset deliver_freeze so that we won't try to move the spool files further down */
deliver_freeze = FALSE;
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
(void) event_raise(event_action, US"msg:complete", NULL);
#endif
}
FILE *wmf = NULL;
FILE *f = fdopen(fd, "wb");
uschar * bound;
+ int topt;
if (warn_message_file)
if (!(wmf = Ufopen(warn_message_file, "rb")))
if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0)
fprintf(f,"Original-Envelope-ID: %s\n", dsn_envid);
else
- fprintf(f,"X-Original-Envelope-ID: error decoding xtext formated ENVID\n");
+ fprintf(f,"X-Original-Envelope-ID: error decoding xtext formatted ENVID\n");
}
fputc('\n', f);
fflush(f);
/* header only as required by RFC. only failure DSN needs to honor RET=FULL */
- int topt = topt_add_return_path | topt_no_body;
+ topt = topt_add_return_path | topt_no_body;
transport_filter_argv = NULL; /* Just in case */
return_path = sender_address; /* In case not previously set */
/* Write the original email out */
if (remove_journal)
{
- sprintf(CS spoolname, "%s/input/%s/%s-J", spool_directory, message_subdir, id);
+ snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-J",
+ spool_directory, queue_name, message_subdir, id);
if (Uunlink(spoolname) < 0 && errno != ENOENT)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s", spoolname,
strerror(errno));
regex_must_compile(US"\\n250[\\s\\-]PRDR(\\s|\\n|$)", FALSE, TRUE);
#endif
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
if (!regex_UTF8) regex_UTF8 =
regex_must_compile(US"\\n250[\\s\\-]SMTPUTF8(\\s|\\n|$)", FALSE, TRUE);
#endif
int rc;
uschar * new_sender_address,
* save_sender_address;
+BOOL save_qr = queue_running;
+
+/* make spool_open_datafile non-noisy on fail */
+
+queue_running = TRUE;
+
+/* Side effect: message_subdir is set for the (possibly split) spool directory */
-if (!spool_open_datafile(id))
+deliver_datafile = spool_open_datafile(id);
+queue_running = save_qr;
+if (deliver_datafile < 0)
return NULL;
/* Save and restore the global sender_address. I'm not sure if we should