{
#ifdef HAVE_STATFS
struct STATVFS statbuf;
+struct stat dummy;
uschar *path;
uschar *name;
uschar buffer[1024];
memset(&statbuf, 0, sizeof(statbuf));
if (STATVFS(CS path, &statbuf) != 0)
- {
- log_write(0, LOG_MAIN|LOG_PANIC, "cannot accept message: failed to stat "
- "%s directory %s: %s", name, spool_directory, strerror(errno));
- smtp_closedown(US"spool or log directory problem");
- exim_exit(EXIT_FAILURE);
- }
+ if (stat(CS path, &dummy) == -1 && errno == ENOENT)
+ { /* Can happen on first run after installation */
+ *inodeptr = -1;
+ return -1;
+ }
+ else
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "cannot accept message: failed to stat "
+ "%s directory %s: %s", name, path, strerror(errno));
+ smtp_closedown(US"spool or log directory problem");
+ exim_exit(EXIT_FAILURE);
+ }
*inodeptr = (statbuf.F_FILES > 0)? statbuf.F_FAVAIL : -1;
return (int)(((double)statbuf.F_BAVAIL * (double)statbuf.F_FRSIZE)/1024.0);
+#else
/* Unable to find partition sizes in this environment. */
-#else
*inodeptr = -1;
return -1;
#endif
{
log_write(L_lost_incoming_connection | L_smtp_connection, LOG_MAIN,
"%s lost while reading message data%s", smtp_get_connection_info(), s);
+smtp_notquit_exit(US"connection-lost", NULL, NULL);
return US"421 Lost incoming connection";
}
int c = (receive_getc)();
if (c != EOF) (receive_ungetc)(c); else
{
- uschar *msg = US"SMTP connection lost after final dot";
+ smtp_notquit_exit(US"connection-lost", NULL, NULL);
smtp_reply = US""; /* No attempt to send a response */
smtp_yield = FALSE; /* Nothing more on this connection */
/* Re-use the log line workspace */
sptr = 0;
- s = string_cat(s, &size, &sptr, msg);
+ s = string_cat(s, &size, &sptr, US"SMTP connection lost after final dot");
s = add_host_info_for_log(s, &size, &sptr);
s[sptr] = 0;
log_write(0, LOG_MAIN, "%s", s);
Send dot onward. If accepted, wipe the spooled files, log as delivered and accept
the sender's dot (below).
If rejected: copy response to sender, wipe the spooled files, log approriately.
- If temp-reject: accept to sender, keep the spooled files.
+ If temp-reject: normally accept to sender, keep the spooled file - unless defer=pass
+ in which case pass temp-reject back to initiator and dump the files.
Having the normal spool files lets us do data-filtering, and store/forward on temp-reject.
cutthrough_done = ACCEPTED;
break; /* message_id needed for SMTP accept below */
+ case '4': /* Temp-reject. Keep spoolfiles and accept, unless defer-pass mode.
+ ... for which, pass back the exact error */
+ if (cutthrough.defer_pass) smtp_reply = string_copy_malloc(msg);
+ /*FALLTRHOUGH*/
+
default: /* Unknown response, or error. Treat as temp-reject. */
- case '4': /* Temp-reject. Keep spoolfiles and accept. */
cutthrough_done = TMP_REJ; /* Avoid the usual immediate delivery attempt */
break; /* message_id needed for SMTP accept below */
case '5': /* Perm-reject. Do the same to the source. Dump any spoolfiles */
- smtp_reply= msg; /* Pass on the exact error */
+ smtp_reply = string_copy_malloc(msg); /* Pass on the exact error */
cutthrough_done = PERM_REJ;
break;
}
/* smtp_reply is set non-empty */
else if (smtp_reply[0] != 0)
- {
if (fake_response != OK && (smtp_reply[0] == '2'))
smtp_respond((fake_response == DEFER)? US"450" : US"550", 3, TRUE,
fake_response_text);
else
smtp_printf("%.1024s\r\n", smtp_reply);
- }
switch (cutthrough_done)
{
- case ACCEPTED: log_write(0, LOG_MAIN, "Completed");/* Delivery was done */
+ case ACCEPTED:
+ log_write(0, LOG_MAIN, "Completed");/* Delivery was done */
case PERM_REJ:
- { /* Delete spool files */
- Uunlink(spool_fname(US"input", message_subdir, message_id, US"-D"));
- Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H"));
- Uunlink(spool_fname(US"msglog", message_subdir, message_id, US""));
- }
- case TMP_REJ: message_id[0] = 0; /* Prevent a delivery from starting */
- default:break;
+ /* Delete spool files */
+ Uunlink(spool_fname(US"input", message_subdir, message_id, US"-D"));
+ Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H"));
+ Uunlink(spool_fname(US"msglog", message_subdir, message_id, US""));
+ message_id[0] = 0; /* Prevent a delivery from starting */
+ break;
+
+ case TMP_REJ:
+ if (cutthrough.defer_pass)
+ {
+ Uunlink(spool_fname(US"input", message_subdir, message_id, US"-D"));
+ Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H"));
+ Uunlink(spool_fname(US"msglog", message_subdir, message_id, US""));
+ }
+ message_id[0] = 0; /* Prevent a delivery from starting */
+ default:
+ break;
}
cutthrough.delivery = FALSE;
+ cutthrough.defer_pass = FALSE;
}
/* For batched SMTP, generate an error message on failure, and do