From a2da3176aa39ec9aa5ae495e5a6d533477f871aa Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 7 May 2016 21:27:52 +0100 Subject: global queue_name --- src/exim_monitor/em_globals.c | 2 ++ src/exim_monitor/em_menu.c | 18 +++++------ src/exim_monitor/em_queue.c | 15 ++++----- src/src/dcc.c | 10 +++--- src/src/deliver.c | 71 ++++++++++++++++++++++++------------------- src/src/globals.c | 1 + src/src/globals.h | 1 + src/src/queue.c | 44 +++++++++++++++------------ src/src/receive.c | 66 ++++++++++++++++++++-------------------- src/src/spool_in.c | 16 +++++----- src/src/spool_mbox.c | 11 +++---- src/src/spool_out.c | 18 ++++++----- src/src/transport.c | 12 +++++--- 13 files changed, 156 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/exim_monitor/em_globals.c b/src/exim_monitor/em_globals.c index 6415e4238..9221ae2da 100644 --- a/src/exim_monitor/em_globals.c +++ b/src/exim_monitor/em_globals.c @@ -187,6 +187,8 @@ uid_t originator_uid; uschar *primary_hostname = NULL; +uschar *queue_name = US""; + int received_count = 0; uschar *received_protocol = NULL; int received_time = 0; diff --git a/src/exim_monitor/em_menu.c b/src/exim_monitor/em_menu.c index 51a952e99..ccdfa05ba 100644 --- a/src/exim_monitor/em_menu.c +++ b/src/exim_monitor/em_menu.c @@ -148,10 +148,10 @@ call_data = call_data; for (i = 0; i < (spool_is_split? 2:1); i++) { message_subdir[0] = (i != 0)? ((uschar *)client_data)[5] : 0; - sprintf(CS buffer, "%s/msglog/%s/%s", spool_directory, message_subdir, - (uschar *)client_data); - f = fopen(CS buffer, "r"); - if (f != NULL) break; + snprintf(CS buffer, sizeof(buffer), "%s/msglog/%s/%s/%s", + spool_directory, queue_name, message_subdir, (uschar *)client_data); + if ((f = fopen(CS buffer, "r"))) + break; } if (f == NULL) @@ -181,11 +181,11 @@ call_data = call_data; for (i = 0; i < (spool_is_split? 2:1); i++) { - message_subdir[0] = (i != 0)? ((uschar *)client_data)[5] : 0; - sprintf(CS buffer, "%s/input/%s/%s-D", spool_directory, message_subdir, - (uschar *)client_data); - f = fopen(CS buffer, "r"); - if (f != NULL) break; + message_subdir[0] = i != 0 ? ((uschar *)client_data)[5] : 0; + snprintf(CS buffer, sizeof(buffer), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, (uschar *)client_data); + if ((f = fopen(CS buffer, "r"))) + break; } if (f == NULL) diff --git a/src/exim_monitor/em_queue.c b/src/exim_monitor/em_queue.c index c01a80fe0..893e43898 100644 --- a/src/exim_monitor/em_queue.c +++ b/src/exim_monitor/em_queue.c @@ -263,7 +263,8 @@ else sender_address = NULL; -sprintf(CS buffer, "%s/input/%s/%s-D", spool_directory, message_subdir, name); +snprintf(CS buffer, sizeof(buffer), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, name); if (Ustat(buffer, &statdata) == 0) q->size = message_size + statdata.st_size - SPOOL_DATA_START_OFFSET + 1; @@ -271,7 +272,6 @@ if (Ustat(buffer, &statdata) == 0) been delivered, and removing visible names. */ if (recipients_list != NULL) - { for (i = 0; i < recipients_count; i++) { uschar *r = recipients_list[i].address; @@ -282,7 +282,6 @@ if (recipients_list != NULL) (void)find_dest(q, r, dest_add, FALSE); } } - } /* Recover the dynamic store used by spool_read_header(). */ @@ -617,11 +616,13 @@ uschar buffer[1024]; message_subdir[0] = p->dir_char; -sprintf(CS buffer, "%s/input/%s/%s-J", spool_directory, message_subdir, p->name); -jread = fopen(CS buffer, "r"); -if (jread == NULL) +snprintf(CS buffer, sizeof(buffer), "%s/input/%s/%s/%s-J", + spool_directory, queue_name, message_subdir, p->name); + +if (!(jread = fopen(CS buffer, "r"))) { - sprintf(CS buffer, "%s/input/%s/%s-H", spool_directory, message_subdir, p->name); + snprintf(CS buffer, sizeof(buffer), "%s/input/%s/%s/%s-H", + spool_directory, queue_name, message_subdir, p->name); if (Ustat(buffer, &statdata) < 0 || p->update_time == statdata.st_mtime) return; } diff --git a/src/src/dcc.c b/src/src/dcc.c index c9d0db236..2d9c16528 100644 --- a/src/src/dcc.c +++ b/src/src/dcc.c @@ -102,14 +102,14 @@ dcc_process(uschar **listptr) message_subdir[1] = '\0'; for (i = 0; i < 2; i++) { - message_subdir[0] = (split_spool_directory == (i == 0))? message_id[5] : 0; - sprintf(CS mbox_path, "%s/input/%s/%s-D", spool_directory, message_subdir, message_id); - data_file = Ufopen(mbox_path,"rb"); - if (data_file != NULL) + message_subdir[0] = split_spool_directory == (i == 0) ? message_id[5] : 0; + snprintf(CS mbox_path, sizeof(mbox_path), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, message_id); + if ((data_file = Ufopen(mbox_path,"rb"))) break; } - if (data_file == NULL) + if (!data_file) { /* error while spooling */ log_write(0, LOG_MAIN|LOG_PANIC, diff --git a/src/src/deliver.c b/src/src/deliver.c index 743fc83e8..631a3e18a 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -285,9 +285,9 @@ int fd = Uopen(filename, O_WRONLY|O_APPEND|O_CREAT, mode); 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); } @@ -1946,7 +1946,8 @@ if ( !shadowing { 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) @@ -4372,11 +4373,10 @@ for (delivery_count = 0; addr_remote; delivery_count++) 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)); @@ -5231,8 +5231,8 @@ if ((rc = spool_read_header(spoolname, TRUE, TRUE)) != spool_read_OK) 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); @@ -5257,13 +5257,17 @@ if ((rc = spool_read_header(spoolname, TRUE, TRUE)) != spool_read_OK) 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)); @@ -5283,9 +5287,10 @@ existence, as it will get further successful deliveries added to it in this 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)) { @@ -5404,10 +5409,10 @@ if (message_logs) 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)); @@ -6638,10 +6643,10 @@ therein are added to the non-recipients. */ 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)); @@ -7505,12 +7510,13 @@ if (!addr_defer) { 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", @@ -7529,11 +7535,13 @@ if (!addr_defer) /* 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)); @@ -8003,7 +8011,8 @@ if (journal_fd >= 0) (void)close(journal_fd); 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)); diff --git a/src/src/globals.c b/src/src/globals.c index be1fae849..8b2287aca 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1020,6 +1020,7 @@ BOOL queue_2stage = FALSE; uschar *queue_domains = NULL; int queue_interval = -1; BOOL queue_list_requires_admin = TRUE; +uschar *queue_name = US""; BOOL queue_only = FALSE; uschar *queue_only_file = NULL; int queue_only_load = -1; diff --git a/src/src/globals.h b/src/src/globals.h index 72bb13919..bd7518074 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -669,6 +669,7 @@ extern BOOL queue_running; /* TRUE for queue running process and */ extern pid_t queue_run_pid; /* PID of the queue running process or 0 */ extern int queue_run_pipe; /* Pipe for synchronizing */ extern int queue_interval; /* Queue running interval */ +extern uschar *queue_name; /* Name of queue, if nondefault spooling */ extern BOOL queue_only; /* TRUE to disable immediate delivery */ extern int queue_only_load; /* Max load before auto-queue */ extern BOOL queue_only_load_latch; /* Latch queue_only_load TRUE */ diff --git a/src/src/queue.c b/src/src/queue.c index cc8d36b23..c97179092 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -142,7 +142,8 @@ else i = subdiroffset; /* Set up prototype for the directory name. */ -sprintf(CS buffer, "%s/input", spool_directory); +snprintf(CS buffer, sizeof(buffer), "%s/input/%s", spool_directory, queue_name); +buffer[sizeof(buffer) - 3] = 0; subptr = Ustrlen(buffer); buffer[subptr+2] = 0; /* terminator for lengthened name */ @@ -161,8 +162,8 @@ for (; i <= *subcount; i++) buffer[subptr+1] = subdirchar; } - dd = opendir(CS buffer); - if (dd == NULL) continue; + if (!(dd = opendir(CS buffer))) + continue; /* Now scan the directory. */ @@ -265,7 +266,8 @@ for (; i <= *subcount; i++) if (!split_spool_directory && count <= 2) { rmdir(CS buffer); - sprintf(CS big_buffer, "%s/msglog/%c", spool_directory, subdirchar); + sprintf(CS big_buffer, "%s/msglog/%s/%c", + spool_directory, queue_name, subdirchar); rmdir(CS big_buffer); } if (subdiroffset > 0) break; /* Single sub-directory */ @@ -476,8 +478,8 @@ for (i = (queue_run_in_order? -1 : 0); /* Check that the message still exists */ message_subdir[0] = f->dir_uschar; - sprintf(CS buffer, "%s/input/%s/%s", spool_directory, message_subdir, - f->text); + snprintf(CS buffer, sizeof(buffer), "%s/input/%s/%s/%s", + spool_directory, queue_name, message_subdir, f->text); if (Ustat(buffer, &statbuf) < 0) continue; /* There are some tests that require the reading of the header file. Ensure @@ -842,8 +844,8 @@ for (; f != NULL; f = f->next) FILE *jread; struct stat statbuf; - sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir, - f->text); + sprintf(CS big_buffer, "%s/input/%s/%s/%s", + spool_directory, queue_name, message_subdir, f->text); ptr = Ustrlen(big_buffer)-1; big_buffer[ptr] = 'D'; @@ -892,8 +894,8 @@ for (; f != NULL; f = f->next) if (save_errno == ERRNO_SPOOLFORMAT) { struct stat statbuf; - sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir, - f->text); + sprintf(CS big_buffer, "%s/input/%s/%s/%s", + spool_directory, queue_name, message_subdir, f->text); if (Ustat(big_buffer, &statbuf) == 0) printf("*** spool format error: size=" OFF_T_FMT " ***", statbuf.st_size); @@ -1004,12 +1006,15 @@ if (action >= MSG_SHOW_BODY) for (i = 0; i < 2; i++) { - message_subdir[0] = (split_spool_directory == (i == 0))? id[5] : 0; - sprintf(CS spoolname, "%s/%s/%s/%s%s", spool_directory, subdirectory, - message_subdir, id, suffix); - fd = Uopen(spoolname, O_RDONLY, 0); - if (fd >= 0) break; - if (i == 0) continue; + message_subdir[0] = split_spool_directory == (i == 0) ? id[5] : 0; + snprintf(CS spoolname, sizeof(spoolname), "%s/%s/%s/%s/%s%s", + spool_directory, subdirectory, queue_name, + message_subdir, id, suffix); + if ((fd = Uopen(spoolname, O_RDONLY, 0)) >= 0) + break; + if (i == 0) + continue; + printf("Failed to open %s file for %s%s: %s\n", subdirectory, id, suffix, strerror(errno)); if (action == MSG_SHOW_LOG && !message_logs) @@ -1162,7 +1167,8 @@ switch(action) message_subdir[0] = id[5]; for (j = 0; j < 2; message_subdir[0] = 0, j++) { - 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 (Uunlink(spoolname) < 0) { if (errno != ENOENT) @@ -1176,8 +1182,8 @@ switch(action) for (i = 0; i < 3; i++) { - sprintf(CS spoolname, "%s/input/%s/%s-%c", spool_directory, message_subdir, - id, "DHJ"[i]); + snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-%c", + spool_directory, queue_name, message_subdir, id, "DHJ"[i]); if (Uunlink(spoolname) < 0) { if (errno != ENOENT) diff --git a/src/src/receive.c b/src/src/receive.c index 2628570d8..ea99cfb2b 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -2471,7 +2471,7 @@ it will fit. */ to be the least significant base-62 digit of the time of arrival. Otherwise ensure that it is an empty string. */ -message_subdir[0] = split_spool_directory? message_id[5] : 0; +message_subdir[0] = split_spool_directory ? message_id[5] : 0; /* Now that we have the message-id, if there is no message-id: header, generate one, but only for local (without suppress_local_fixups) or submission mode @@ -2863,16 +2863,17 @@ to access it both via a file descriptor and a stream. Try to make the directory if it isn't there. Note re use of sprintf: spool_directory is checked on input to be < 200 characters long. */ -sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory, message_subdir, - message_id); -data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE); -if (data_fd < 0) +snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, message_id); +DEBUG(D_receive) debug_printf("Data file name: %s\n", spool_name); + +if ((data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE)) < 0) { if (errno == ENOENT) { - uschar temp[16]; - sprintf(CS temp, "input/%s", message_subdir); - if (message_subdir[0] == 0) temp[5] = 0; + uschar * temp = string_sprintf("input%s%s%s%s", + *queue_name ? "/" : "", queue_name, + *message_subdir ? "/" : "", message_subdir); (void)directory_make(spool_directory, temp, INPUT_DIRECTORY_MODE, TRUE); data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE); } @@ -3649,11 +3650,11 @@ signal(SIGINT, SIG_IGN); deliver_firsttime = TRUE; #ifdef EXPERIMENTAL_BRIGHTMAIL -if (bmi_run == 1) { - /* rewind data file */ +if (bmi_run == 1) + { /* rewind data file */ lseek(data_fd, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET); bmi_verdicts = bmi_process_message(header_list, data_fd); -}; + } #endif /* Update the timstamp in our Received: header to account for any time taken by @@ -3691,7 +3692,6 @@ if (host_checking || blackholed_by != NULL) /* Write the -H file */ else - { if ((msg_size = spool_write_header(message_id, SW_RECEIVING, &errmsg)) < 0) { log_write(0, LOG_MAIN, "Message abandoned: %s", errmsg); @@ -3711,7 +3711,6 @@ else /* Does not return */ } } - } /* The message has now been successfully received. */ @@ -3859,15 +3858,16 @@ if (message_logs && blackholed_by == NULL) { int fd; - sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, message_subdir, - message_id); - fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE); - - if (fd < 0 && errno == ENOENT) + snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s", + spool_directory, queue_name, message_subdir, message_id); + + if ( (fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE)) < 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(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE); } @@ -3953,16 +3953,16 @@ if (smtp_input && sender_host_address != NULL && !sender_host_notsocket && /* Delete the files for this aborted message. */ - sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); - sprintf(CS spool_name, "%s/input/%s/%s-H", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-H", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); - sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); goto TIDYUP; @@ -4118,14 +4118,14 @@ if (smtp_input) { case ACCEPTED: log_write(0, LOG_MAIN, "Completed");/* Delivery was done */ case PERM_REJ: { /* Delete spool files */ - sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); - sprintf(CS spool_name, "%s/input/%s/%s-H", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-H", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); - sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); } case TMP_REJ: message_id[0] = 0; /* Prevent a delivery from starting */ diff --git a/src/src/spool_in.c b/src/src/spool_in.c index cafca603d..6341387a2 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -50,8 +50,11 @@ splitting state. */ for (i = 0; i < 2; i++) { int save_errno; - message_subdir[0] = (split_spool_directory == (i == 0))? id[5] : 0; - sprintf(CS spoolname, "%s/input/%s/%s-D", spool_directory, message_subdir, id); + message_subdir[0] = split_spool_directory == (i == 0) ? id[5] : 0; + snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, id); + DEBUG(D_deliver) debug_printf("Trying spool file %s\n", spoolname); + if ((fd = Uopen(spoolname, O_RDWR | O_APPEND, 0)) >= 0) break; save_errno = errno; @@ -318,11 +321,10 @@ and unsplit directories, as for the data file above. */ for (n = 0; n < 2; n++) { if (!subdir_set) - message_subdir[0] = (split_spool_directory == (n == 0))? name[5] : 0; - sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir, - name); - f = Ufopen(big_buffer, "rb"); - if (f != NULL) break; + message_subdir[0] = split_spool_directory == (n == 0) ? name[5] : 0; + sprintf(CS big_buffer, "%s/input/%s/%s/%s", + spool_directory, queue_name, message_subdir, name); + if ((f = Ufopen(big_buffer, "rb"))) break; if (n != 0 || subdir_set || errno != ENOENT) return spool_read_notopen; } diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c index ada3f3693..7ee34b551 100644 --- a/src/src/spool_mbox.c +++ b/src/src/spool_mbox.c @@ -113,17 +113,16 @@ if (!spool_mbox_ok) message_subdir[1] = '\0'; for (i = 0; i < 2; i++) { - message_subdir[0] = (split_spool_directory == (i == 0))? message_id[5] : 0; - temp_string = string_sprintf("%s/input/%s/%s-D", spool_directory, - message_subdir, message_id); - data_file = Ufopen(temp_string, "rb"); - if (data_file != NULL) break; + message_subdir[0] = split_spool_directory == (i == 0) ? message_id[5] : 0; + temp_string = string_sprintf("%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, message_id); + if ((data_file = Ufopen(temp_string, "rb"))) break; } } else data_file = Ufopen(source_file_override, "rb"); - if (data_file == NULL) + if (!data_file) { log_write(0, LOG_MAIN|LOG_PANIC, "Could not open datafile for message %s", message_id); diff --git a/src/src/spool_out.c b/src/src/spool_out.c index e960907db..c7a0043f5 100644 --- a/src/src/spool_out.c +++ b/src/src/spool_out.c @@ -137,12 +137,13 @@ struct stat statbuf; uschar name[256]; uschar temp_name[256]; -sprintf(CS temp_name, "%s/input/%s/hdr.%d", spool_directory, message_subdir, - (int)getpid()); -fd = spool_open_temp(temp_name); -if (fd < 0) return spool_write_error(where, errmsg, US"open", NULL, NULL); +snprintf(CS temp_name, sizeof(temp_name), "%s/input/%s/%s/hdr.%d", + spool_directory, queue_name, message_subdir, (int)getpid()); + +if ((fd = spool_open_temp(temp_name)) < 0) + return spool_write_error(where, errmsg, US"open", NULL, NULL); f = fdopen(fd, "wb"); -DEBUG(D_receive|D_deliver) debug_printf("Writing spool header file\n"); +DEBUG(D_receive|D_deliver) debug_printf("Writing spool header file: %s\n", temp_name); /* We now have an open file to which the header data is to be written. Start with the file's leaf name, to make the file self-identifying. Continue with the @@ -342,7 +343,9 @@ if (fclose(f) != 0) /* Rename the file to its correct name, thereby replacing any previous incarnation. */ -sprintf(CS name, "%s/input/%s/%s-H", spool_directory, message_subdir, id); +snprintf(CS name, sizeof(name), "%s/input/%s/%s/%s-H", + spool_directory, queue_name, message_subdir, id); +DEBUG(D_receive|D_deliver) debug_printf("Renaming spool header file: %s\n", name); if (Urename(temp_name, name) < 0) return spool_write_error(where, errmsg, US"rename", temp_name, NULL); @@ -359,7 +362,8 @@ these cases. One hack on top of another... but that's life. */ #ifdef NEED_SYNC_DIRECTORY -sprintf(CS temp_name, "%s/input/%s/.", spool_directory, message_subdir); +snprintf(CS temp_name, sizeof(temp_name), "%s/input/%s/%s/.", + spool_directory, queue_name, message_subdir); #ifndef O_DIRECTORY #define O_DIRECTORY 0 diff --git a/src/src/transport.c b/src/src/transport.c index 86350ba9d..0fc2b2e09 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -1027,8 +1027,9 @@ if (!(dkim_private_key && dkim_domain && dkim_selector)) check_string, escape_string, rewrite_rules, rewrite_existflags); -(void)string_format(dkim_spool_name, 256, "%s/input/%s/%s-%d-K", - spool_directory, message_subdir, message_id, (int)getpid()); +(void)string_format(dkim_spool_name, sizeof(dkim_spool_name), + "%s/input/%s/%s/%s-%d-K", + spool_directory, queue_name, message_subdir, message_id, (int)getpid()); if ((dkim_fd = Uopen(dkim_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE)) < 0) { @@ -1755,10 +1756,11 @@ while (1) for (i = msgq_count - 1; i >= 0; --i) if (msgq[i].bKeep) { if (split_spool_directory) - sprintf(CS spool_file, "%s%c/%s-D", - spool_dir, msgq[i].message_id[5], msgq[i].message_id); + snprintf(CS spool_file, sizeof(spool_file), "%s/%s/%c/%s-D", + spool_dir, queue_name, msgq[i].message_id[5], msgq[i].message_id); else - sprintf(CS spool_file, "%s%s-D", spool_dir, msgq[i].message_id); + snprintf(CS spool_file, sizeof(spool_file), "%s/%s/%s-D", + spool_dir, queue_name, msgq[i].message_id); if (Ustat(spool_file, &statbuf) != 0) msgq[i].bKeep = FALSE; -- cgit v1.2.3 From 28b3821f89f89670a08603c50662d468e82510ad Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 7 May 2016 23:11:18 +0100 Subject: Command-line options --- doc/doc-docbook/spec.xfpt | 17 ++++++++++++++++- doc/doc-txt/NewStuff | 3 +++ src/src/exim.c | 26 ++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index ba32403d6..2018af992 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -3825,6 +3825,12 @@ This option is not intended for use by external callers. It is used internally by Exim in conjunction with the &%-MC%& option. It signifies that the remote host supports the ESMTP &_DSN_& extension. +.vitem &%-MCG%& +.oindex "&%-MCG%&" +This option is not intended for use by external callers. It is used internally +by Exim in conjunction with the &%-MC%& option. It signifies that an +alternate queue is used, named by the following option. + .vitem &%-MCP%& .oindex "&%-MCP%&" This option is not intended for use by external callers. It is used internally @@ -4456,8 +4462,17 @@ The &'l'& (the letter &"ell"&) flag specifies that only local deliveries are to be done. If a message requires any remote deliveries, it remains on the queue for later delivery. -.vitem &%-q%&<&'qflags'&>&~<&'start&~id'&>&~<&'end&~id'&> +.vitem &%-q[q][i][f[f]][l][G]%& +.oindex "&%-qG%&" +.cindex queue named +.cindex "named queues" .cindex "queue" "delivering specific messages" +If the &'G'& flag and a name is present, the queue runner operates on the +queue with the given name rather than the default queue. +Because the name is the remainder of the option string, any +periodic-run interval must be given as a separate &%-q%& option. + +.vitem &%-q%&<&'qflags'&>&~<&'start&~id'&>&~<&'end&~id'&> When scanning the queue, Exim can be made to skip over messages whose ids are lexically less than a given value by following the &%-q%& option with a starting message id. For example: diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 07e6f1dba..1207c4974 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -12,6 +12,9 @@ Version 4.88 1. The new perl_tainmode option allows to run the embedded perl interpreter in taint mode. + 2. Facility for named queues. A commandline argument can specify + the queue name for a queue-runner. + Version 4.87 ------------ diff --git a/src/src/exim.c b/src/src/exim.c index 4ea42fdc2..6432a4c2f 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2716,12 +2716,22 @@ for (i = 1; i < argc; i++) /* -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; } + /* -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; + } + /* -MCP: set the smtp_use_pipelining flag; this is useful only when it preceded -MC (see above) */ @@ -2737,9 +2747,9 @@ for (i = 1; i < argc; i++) else if (Ustrcmp(argrest, "CQ") == 0) { - if(++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); + if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); else badarg = TRUE; - if(++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); + if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); else badarg = TRUE; break; } @@ -3229,8 +3239,16 @@ for (i = 1; i < argc; i++) argrest++; } - /* -q[f][f][l]: Run the queue, optionally forced, optionally local only, - optionally starting from a given message id. */ + /* -q[f][f][l][G]... Run the named queue */ + + if (*argrest == 'G') + { + queue_name = string_copy(argrest); + do ++argrest; while (*argrest); + } + + /* -q[f][f][l][G]: 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]))) -- cgit v1.2.3 From b0b9dbb191f8c60bf7233338a9a0a14c72f1f7a0 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 7 May 2016 23:55:46 +0100 Subject: ACL modifier --- doc/doc-docbook/spec.xfpt | 8 ++++++++ doc/doc-txt/NewStuff | 3 ++- src/src/acl.c | 17 ++++++++++++++--- 3 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 2018af992..8b615f831 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -28583,6 +28583,14 @@ all the conditions are true, wherever it appears in an ACL command, whereas effect. +.vitem &*queue*&&~=&~<&'text'&> +This modifier specifies the use of a named queue for spool files +for the message. +This could be used, for example, for known high-volume burst sources +of traffic, or for quarantine of messages. +Separate queue-runner processes will be needed for named queues. + + .vitem &*remove_header*&&~=&~<&'text'&> This modifier specifies one or more header names in a colon-separated list that are to be removed from an incoming message, assuming, of course, that diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 1207c4974..aabeff338 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -13,7 +13,8 @@ Version 4.88 interpreter in taint mode. 2. Facility for named queues. A commandline argument can specify - the queue name for a queue-runner. + the queue name for a queue-runner, and an ACL modifier can set + the queue to be used for a message. Version 4.87 diff --git a/src/src/acl.c b/src/src/acl.c index 474b0d181..ec1505bf0 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -88,6 +88,7 @@ enum { ACLC_ACL, #ifdef WITH_CONTENT_SCAN ACLC_MIME_REGEX, #endif + ACLC_QUEUE, ACLC_RATELIMIT, ACLC_RECIPIENTS, #ifdef WITH_CONTENT_SCAN @@ -108,7 +109,7 @@ enum { ACLC_ACL, ACLC_VERIFY }; /* ACL conditions/modifiers: "delay", "control", "continue", "endpass", -"message", "log_message", "log_reject_target", "logwrite", and "set" are +"message", "log_message", "log_reject_target", "logwrite", "queue" and "set" are modifiers that look like conditions but always return TRUE. They are used for their side effects. */ @@ -152,13 +153,16 @@ static uschar *conditions[] = { #ifdef WITH_CONTENT_SCAN US"mime_regex", #endif + US"queue", US"ratelimit", US"recipients", #ifdef WITH_CONTENT_SCAN US"regex", #endif US"remove_header", - US"sender_domains", US"senders", US"set", + US"sender_domains", + US"senders", + US"set", #ifdef WITH_CONTENT_SCAN US"spam", #endif @@ -298,6 +302,7 @@ static uschar cond_expand_at_top[] = { #ifdef WITH_CONTENT_SCAN TRUE, /* mime_regex */ #endif + TRUE, /* queue */ TRUE, /* ratelimit */ FALSE, /* recipients */ #ifdef WITH_CONTENT_SCAN @@ -360,6 +365,7 @@ static uschar cond_modifiers[] = { #ifdef WITH_CONTENT_SCAN FALSE, /* mime_regex */ #endif + TRUE, /* queue */ FALSE, /* ratelimit */ FALSE, /* recipients */ #ifdef WITH_CONTENT_SCAN @@ -507,6 +513,7 @@ static unsigned int cond_forbids[] = { ~(1<next) rc = match_isinlist(dkim_cur_signer, &arg,0,NULL,NULL,MCL_STRING,TRUE,NULL); else - rc = FAIL; + rc = FAIL; break; case ACLC_DKIM_STATUS: @@ -3677,6 +3684,10 @@ for (; cb != NULL; cb = cb->next) break; #endif + case ACLC_QUEUE: + queue_name = string_copy_malloc(arg); + break; + case ACLC_RATELIMIT: rc = acl_ratelimit(arg, where, log_msgptr); break; -- cgit v1.2.3 From 6073ad45c336ac31081bb1625f5415dc41344641 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 8 May 2016 01:05:54 +0100 Subject: testcase --- doc/doc-docbook/spec.xfpt | 7 +++++++ src/src/exim.c | 8 ++++++-- src/src/queue.c | 13 +++++++++++-- test/confs/0574 | 45 ++++++++++++++++++++++++++++++++++++++++++++ test/log/0574 | 17 +++++++++++++++++ test/scripts/0000-Basic/0574 | 36 +++++++++++++++++++++++++++++++++++ test/stdout/0574 | 11 +++++++++++ 7 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 test/confs/0574 create mode 100644 test/log/0574 create mode 100644 test/scripts/0000-Basic/0574 create mode 100644 test/stdout/0574 (limited to 'src') diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 8b615f831..4bc2e1118 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -3825,11 +3825,13 @@ This option is not intended for use by external callers. It is used internally by Exim in conjunction with the &%-MC%& option. It signifies that the remote host supports the ESMTP &_DSN_& extension. +.new .vitem &%-MCG%& .oindex "&%-MCG%&" This option is not intended for use by external callers. It is used internally by Exim in conjunction with the &%-MC%& option. It signifies that an alternate queue is used, named by the following option. +.wen .vitem &%-MCP%& .oindex "&%-MCP%&" @@ -4462,6 +4464,7 @@ The &'l'& (the letter &"ell"&) flag specifies that only local deliveries are to be done. If a message requires any remote deliveries, it remains on the queue for later delivery. +.new .vitem &%-q[q][i][f[f]][l][G]%& .oindex "&%-qG%&" .cindex queue named @@ -4471,6 +4474,7 @@ If the &'G'& flag and a name is present, the queue runner operates on the queue with the given name rather than the default queue. Because the name is the remainder of the option string, any periodic-run interval must be given as a separate &%-q%& option. +.wen .vitem &%-q%&<&'qflags'&>&~<&'start&~id'&>&~<&'end&~id'&> When scanning the queue, Exim can be made to skip over messages whose ids are @@ -28583,12 +28587,15 @@ all the conditions are true, wherever it appears in an ACL command, whereas effect. +.new .vitem &*queue*&&~=&~<&'text'&> This modifier specifies the use of a named queue for spool files for the message. This could be used, for example, for known high-volume burst sources of traffic, or for quarantine of messages. Separate queue-runner processes will be needed for named queues. +If the text after expansion is empty, the default queue is used. +.wen .vitem &*remove_header*&&~=&~<&'text'&> diff --git a/src/src/exim.c b/src/src/exim.c index 6432a4c2f..e4597c287 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -3243,7 +3243,7 @@ for (i = 1; i < argc; i++) if (*argrest == 'G') { - queue_name = string_copy(argrest); + queue_name = string_copy(argrest+1); do ++argrest; while (*argrest); } @@ -4675,7 +4675,11 @@ if (queue_interval == 0 && !daemon_listen) (start_queue_run_id == NULL)? US"" : start_queue_run_id, (stop_queue_run_id == NULL)? US"" : US" stopping at ", (stop_queue_run_id == NULL)? US"" : stop_queue_run_id); - set_process_info("running the queue (single queue run)"); + if (*queue_name) + set_process_info(CS string_sprintf( + "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); exim_exit(EXIT_SUCCESS); } diff --git a/src/src/queue.c b/src/src/queue.c index c97179092..b6dff1107 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -391,7 +391,11 @@ if (!recurse) } log_detail = string_copy(big_buffer); - log_write(L_queue_run, LOG_MAIN, "Start queue run: %s", log_detail); + if (*queue_name) + log_write(L_queue_run, LOG_MAIN, "Start '%s' queue run: %s", + queue_name, log_detail); + else + log_write(L_queue_run, LOG_MAIN, "Start queue run: %s", log_detail); } /* If deliver_selectstring is a regex, compile it. */ @@ -700,7 +704,12 @@ if (queue_2stage) /* At top level, log the end of the run. */ -if (!recurse) log_write(L_queue_run, LOG_MAIN, "End queue run: %s", log_detail); +if (!recurse) + if (*queue_name) + log_write(L_queue_run, LOG_MAIN, "End '%s' queue run: %s", + queue_name, log_detail); + else + log_write(L_queue_run, LOG_MAIN, "End queue run: %s", log_detail); } diff --git a/test/confs/0574 b/test/confs/0574 new file mode 100644 index 000000000..aa3e93a9e --- /dev/null +++ b/test/confs/0574 @@ -0,0 +1,45 @@ +# Exim test configuration 0574 + +SERVER = + +exim_path = EXIM_PATH +keep_environment = +host_lookup_order = bydns +spool_directory = DIR/spool +log_file_path = DIR/spool/log/SERVER%slog +gecos_pattern = "" +gecos_name = CALLER_NAME +tls_advertise_hosts = + +log_selector = +received_recipients +sender_on_delivery + +acl_smtp_rcpt = accept queue = \ + ${if or {{eq {SERVER}{server}}{eq {normal}{$local_part}}} {} {$local_part}} +queue_only +queue_run_in_order + +#--------------- + +begin routers + +dump: + driver = redirect + condition = ${if eq {SERVER}{server}{yes}{no}} + data = :blackhole: + +all: + driver = manualroute + route_list = * 127.0.0.1 + self = send + transport = out + +#--------------- + +begin transports + +out: + driver = smtp + port = PORT_D + +# End + diff --git a/test/log/0574 b/test/log/0574 new file mode 100644 index 000000000..cf13480bc --- /dev/null +++ b/test/log/0574 @@ -0,0 +1,17 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local-smtp S=sss for normal@test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local-smtp S=sss for alternate@test.ex +1999-03-02 09:44:33 Start queue run: pid=pppp -qq +1999-03-02 09:44:33 10HmaX-0005vi-00 => normal@test.ex F= R=all T=out H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaZ-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qq +1999-03-02 09:44:33 Start 'nosuchqueue' queue run: pid=pppp +1999-03-02 09:44:33 End 'nosuchqueue' queue run: pid=pppp +1999-03-02 09:44:33 Start 'alternate' queue run: pid=pppp +1999-03-02 09:44:33 10HmaY-0005vi-00 => alternate@test.ex F= R=all T=out H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbA-0005vi-00" +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 End 'alternate' queue run: pid=pppp + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name H=localhost (the.local.host.name) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@the.local.host.name for normal@test.ex +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name H=localhost (the.local.host.name) [127.0.0.1] P=esmtp S=sss id=E10HmaY-0005vi-00@the.local.host.name for alternate@test.ex diff --git a/test/scripts/0000-Basic/0574 b/test/scripts/0000-Basic/0574 new file mode 100644 index 000000000..53f7a5da1 --- /dev/null +++ b/test/scripts/0000-Basic/0574 @@ -0,0 +1,36 @@ +# named queues +# Exim test configuration 0574 +# +exim -DSERVER=server -bd -oX PORT_D +**** +# +exim -bs +MAIL FROM: +RCPT TO: +DATA +Subject: test + +foo +. +RSET +MAIL FROM: +RCPT TO: +DATA +Subject: test + +foo +. +QUIT +**** +# +exim -qq +**** +# +exim -qGnosuchqueue +**** +# +exim -qGalternate +**** +# +killdaemon +no_msglog_check diff --git a/test/stdout/0574 b/test/stdout/0574 new file mode 100644 index 000000000..47285d74a --- /dev/null +++ b/test/stdout/0574 @@ -0,0 +1,11 @@ +220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaX-0005vi-00 +250 Reset OK +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaY-0005vi-00 +221 the.local.host.name closing connection -- cgit v1.2.3 From afa6d3adc30bd4898825af38763ce008cab5a774 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 8 May 2016 01:24:47 +0100 Subject: logging --- doc/doc-docbook/spec.xfpt | 1 + src/src/deliver.c | 9 +++++++++ src/src/receive.c | 3 +++ test/log/0574 | 4 ++-- 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 4bc2e1118..bb00fa1d2 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -35566,6 +35566,7 @@ the following table: &`P `& on &`<=`& lines: protocol used &` `& on &`=>`& and &`**`& lines: return path &`PRX `& on &'<='& and&`=>`& lines: proxy address +&`Q `& alternate queue name &`QT `& on &`=>`& lines: time spent on queue so far &` `& on &"Completed"& lines: time spent on queue &`R `& on &`<=`& lines: reference for local bounce diff --git a/src/src/deliver.c b/src/src/deliver.c index 631a3e18a..1fd3d46c0 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -880,6 +880,9 @@ if (LOGGING(sender_on_delivery) || msg) 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">"); @@ -1267,6 +1270,9 @@ else if (result == DEFER || result == PANIC) 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 a null string and driver_kind contains "routing" without the leading @@ -1388,6 +1394,9 @@ else 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)) diff --git a/src/src/receive.c b/src/src/receive.c index ea99cfb2b..c783cedfd 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -3804,6 +3804,9 @@ if (LOGGING(8bitmime)) s = string_append(s, &size, &sptr, 2, US" M8S=", big_buffer); } +if (*queue_name) + s = string_append(s, &size, &sptr, 2, US" Q=", queue_name); + /* If an addr-spec in a message-id contains a quoted string, it can contain any characters except " \ and CR and so in particular it can contain NL! Therefore, make sure we use a printing-characters only version for the log. diff --git a/test/log/0574 b/test/log/0574 index cf13480bc..206a95f38 100644 --- a/test/log/0574 +++ b/test/log/0574 @@ -1,5 +1,5 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local-smtp S=sss for normal@test.ex -1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local-smtp S=sss for alternate@test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local-smtp S=sss Q=alternate for alternate@test.ex 1999-03-02 09:44:33 Start queue run: pid=pppp -qq 1999-03-02 09:44:33 10HmaX-0005vi-00 => normal@test.ex F= R=all T=out H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaZ-0005vi-00" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed @@ -7,7 +7,7 @@ 1999-03-02 09:44:33 Start 'nosuchqueue' queue run: pid=pppp 1999-03-02 09:44:33 End 'nosuchqueue' queue run: pid=pppp 1999-03-02 09:44:33 Start 'alternate' queue run: pid=pppp -1999-03-02 09:44:33 10HmaY-0005vi-00 => alternate@test.ex F= R=all T=out H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbA-0005vi-00" +1999-03-02 09:44:33 10HmaY-0005vi-00 => alternate@test.ex F= Q=alternate R=all T=out H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbA-0005vi-00" 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed 1999-03-02 09:44:33 End 'alternate' queue run: pid=pppp -- cgit v1.2.3 From 5aba2a452669cc19defd5732e2512984ecd1603e Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 8 May 2016 01:29:25 +0100 Subject: transport_pass_socket --- src/src/transport.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/src/transport.c b/src/src/transport.c index 0fc2b2e09..9737acc58 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -1929,7 +1929,12 @@ if ((pid = fork()) == 0) argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0); - /* Call with the dsn flag */ + if (*queue_name) + { + argv[i++] = US"-MCG"; + argv[i++] = queue_name; + } + if (smtp_use_dsn) argv[i++] = US"-MCD"; if (smtp_authenticated) argv[i++] = US"-MCA"; -- cgit v1.2.3 From fa665e0b7252b5916f0fbd57d6ef8c1f0a9b080f Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 8 May 2016 13:25:57 +0100 Subject: periodic queue runner --- doc/doc-docbook/spec.xfpt | 7 ++++--- src/src/daemon.c | 5 ++++- src/src/exim.c | 11 +++++++---- test/log/0574 | 10 ++++++++++ test/scripts/0000-Basic/0574 | 22 +++++++++++++++++++++- test/stdout/0574 | 6 ++++++ 6 files changed, 52 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index bb00fa1d2..7b1e1ecb6 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -4465,15 +4465,16 @@ be done. If a message requires any remote deliveries, it remains on the queue for later delivery. .new -.vitem &%-q[q][i][f[f]][l][G]%& +.vitem &%-q[q][i][f[f]][l][G[/