directory if it does not exist. From release 4.21, normal message logs should
be created when the message is received.
directory if it does not exist. From release 4.21, normal message logs should
be created when the message is received.
+ fd = Uopen(filename,
+#ifdef O_CLOEXEC
+ O_CLOEXEC |
+#endif
+#ifdef O_NOFOLLOW
+ O_NOFOLLOW |
+#endif
+ O_WRONLY|O_APPEND|O_CREAT, mode);
+ if (fd >= 0)
+ {
+ /* Set the close-on-exec flag and change the owner to the exim uid/gid (this
+ function is called as root). Double check the mode, because the group setting
+ doesn't always get set automatically. */
+
+#ifndef O_CLOEXEC
+ (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+ if (fchown(fd, exim_uid, exim_gid) < 0)
+ {
+ *error = US"chown";
+ return -1;
+ }
+ if (fchmod(fd, mode) < 0)
+ {
+ *error = US"chmod";
+ return -1;
+ }
+ return fd;
+ }
+ if (errno != ENOENT)
+ break;
+
(void)directory_make(spool_directory,
spool_sname(US"msglog", message_subdir),
MSGLOG_DIRECTORY_MODE, TRUE);
(void)directory_make(spool_directory,
spool_sname(US"msglog", message_subdir),
MSGLOG_DIRECTORY_MODE, TRUE);
- fd = Uopen(filename, O_WRONLY|O_APPEND|O_CREAT, mode);
- }
-
-/* Set the close-on-exec flag and change the owner to the exim uid/gid (this
-function is called as root). Double check the mode, because the group setting
-doesn't always get set automatically. */
-
-if (fd >= 0)
- {
- (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
- if (fchown(fd, exim_uid, exim_gid) < 0)
- {
- *error = US"chown";
- return -1;
- }
- if (fchmod(fd, mode) < 0)
- {
- *error = US"chmod";
- return -1;
- }
{
uschar * fname = spool_fname(US"input", message_subdir, message_id, US"-D");
{
uschar * fname = spool_fname(US"input", message_subdir, message_id, US"-D");
- if ((deliver_datafile = Uopen(fname, O_RDWR | O_APPEND, 0)) < 0)
+ if ((deliver_datafile = Uopen(fname,
+#ifdef O_CLOEXEC
+ O_CLOEXEC |
+#endif
+ O_RDWR | O_APPEND, 0)) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to reopen %s for remote "
"parallel delivery: %s", fname, strerror(errno));
}
/* Set the close-on-exec flag */
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to reopen %s for remote "
"parallel delivery: %s", fname, strerror(errno));
}
/* Set the close-on-exec flag */
(void)fcntl(deliver_datafile, F_SETFD, fcntl(deliver_datafile, F_GETFD) |
FD_CLOEXEC);
(void)fcntl(deliver_datafile, F_SETFD, fcntl(deliver_datafile, F_GETFD) |
FD_CLOEXEC);
Arguments:
id the id of the message to be delivered
forced TRUE if delivery was forced by an administrator; this overrides
Arguments:
id the id of the message to be delivered
forced TRUE if delivery was forced by an administrator; this overrides
{
uschar * fname = spool_fname(US"input", message_subdir, id, US"-J");
{
uschar * fname = spool_fname(US"input", message_subdir, id, US"-J");
- if ((jread = Ufopen(fname, "rb")))
+ if ( (journal_fd = Uopen(fname, O_RDWR|O_APPEND
+#ifdef O_CLOEXEC
+ | O_CLOEXEC
+#endif
+#ifdef O_NOFOLLOW
+ | O_NOFOLLOW
+#endif
+ , SPOOL_MODE)) >= 0
+ && lseek(journal_fd, 0, SEEK_SET) == 0
+ && (jread = fdopen(journal_fd, "rb"))
+ )
DEBUG(D_deliver) debug_printf("Previously delivered address %s taken from "
"journal file\n", big_buffer);
}
DEBUG(D_deliver) debug_printf("Previously delivered address %s taken from "
"journal file\n", big_buffer);
}
/* Panic-dies on error */
(void)spool_write_header(message_id, SW_DELIVERING, NULL);
}
/* Panic-dies on error */
(void)spool_write_header(message_id, SW_DELIVERING, NULL);
}
if (!tp)
p->message = string_sprintf("failed to find \"%s\" transport "
"for system filter delivery", tpname);
if (!tp)
p->message = string_sprintf("failed to find \"%s\" transport "
"for system filter delivery", tpname);
-/* If there are any deliveries to be done, open the journal file. This is used
-to record successful deliveries as soon as possible after each delivery is
-known to be complete. A file opened with O_APPEND is used so that several
-processes can run simultaneously.
+/* If there are any deliveries to be and we do not already have the journal
+file, create it. This is used to record successful deliveries as soon as
+possible after each delivery is known to be complete. A file opened with
+O_APPEND is used so that several processes can run simultaneously.
The journal is just insurance against crashes. When the spool file is
ultimately updated at the end of processing, the journal is deleted. If a
The journal is just insurance against crashes. When the spool file is
ultimately updated at the end of processing, the journal is deleted. If a
- uschar * fname = spool_fname(US"input", message_subdir, id, US"-J");
-
- if ((journal_fd = Uopen(fname, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE)) <0)
- log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't open journal file %s: %s",
- fname, strerror(errno));
- return DELIVER_NOT_ATTEMPTED;
- }
+ uschar * fname = spool_fname(US"input", message_subdir, id, US"-J");
+
+ if ((journal_fd = Uopen(fname,
+#ifdef O_CLOEXEC
+ O_CLOEXEC |
+#endif
+ O_WRONLY|O_APPEND|O_CREAT|O_EXCL, SPOOL_MODE)) < 0)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't open journal file %s: %s",
+ fname, strerror(errno));
+ return DELIVER_NOT_ATTEMPTED;
+ }
- /* Set the close-on-exec flag, make the file owned by Exim, and ensure
- that the mode is correct - the group setting doesn't always seem to get
- set automatically. */
+ /* Set the close-on-exec flag, make the file owned by Exim, and ensure
+ that the mode is correct - the group setting doesn't always seem to get
+ set automatically. */
- if( fcntl(journal_fd, F_SETFD, fcntl(journal_fd, F_GETFD) | FD_CLOEXEC)
- || fchown(journal_fd, exim_uid, exim_gid)
- || fchmod(journal_fd, SPOOL_MODE)
- )
- {
- int ret = Uunlink(fname);
- log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't set perms on journal file %s: %s",
- fname, strerror(errno));
- if(ret && errno != ENOENT)
- log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
- fname, strerror(errno));
- return DELIVER_NOT_ATTEMPTED;
+ if( fchown(journal_fd, exim_uid, exim_gid)
+ || fchmod(journal_fd, SPOOL_MODE)
+#ifndef O_CLOEXEC
+ || fcntl(journal_fd, F_SETFD, fcntl(journal_fd, F_GETFD) | FD_CLOEXEC)
+#endif
+ )
+ {
+ int ret = Uunlink(fname);
+ log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't set perms on journal file %s: %s",
+ fname, strerror(errno));
+ if(ret && errno != ENOENT)
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
+ fname, strerror(errno));
+ return DELIVER_NOT_ATTEMPTED;
+ }