diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2019-10-24 23:34:19 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2019-10-25 00:55:45 +0100 |
commit | fc7bae7f2fa3668ada9bd173e9f24c7166e1dd13 (patch) | |
tree | 8efa3fd97a1cfc91694497fbca1cd44b25c810d3 /src | |
parent | 444163417b289354b53d4708760f31d947ac6fd1 (diff) |
Support moving messages across named queues. Bug 2456
Diffstat (limited to 'src')
-rw-r--r-- | src/src/exim.c | 25 | ||||
-rw-r--r-- | src/src/functions.h | 21 | ||||
-rw-r--r-- | src/src/globals.c | 1 | ||||
-rw-r--r-- | src/src/globals.h | 1 | ||||
-rw-r--r-- | src/src/macros.h | 2 | ||||
-rw-r--r-- | src/src/queue.c | 8 | ||||
-rw-r--r-- | src/src/spool_out.c | 26 |
7 files changed, 58 insertions, 26 deletions
diff --git a/src/src/exim.c b/src/src/exim.c index 2b6297bf5..3290d6346 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2787,6 +2787,11 @@ for (i = 1; i < argc; i++) msg_action = MSG_DELIVER; deliver_give_up = TRUE; } + else if (Ustrcmp(argrest, "G") == 0) + { + msg_action = MSG_SETQUEUE; + queue_name_dest = argv[++i]; + } else if (Ustrcmp(argrest, "mad") == 0) { msg_action = MSG_MARK_ALL_DELIVERED; @@ -4064,11 +4069,13 @@ count. Only an admin user can use the test interface to scan for email if (!f.admin_user) { BOOL debugset = (debug_selector & ~D_v) != 0; - if (deliver_give_up || f.daemon_listen || malware_test_file || - (count_queue && queue_list_requires_admin) || - (list_queue && queue_list_requires_admin) || - (queue_interval >= 0 && prod_requires_admin) || - (debugset && !f.running_in_test_harness)) + if ( deliver_give_up || f.daemon_listen || malware_test_file + || count_queue && queue_list_requires_admin + || list_queue && queue_list_requires_admin + || queue_interval >= 0 && prod_requires_admin + || queue_name_dest && prod_requires_admin + || debugset && !f.running_in_test_harness + ) exim_fail("exim:%s permission denied\n", debugset? " debugging" : ""); } @@ -4165,13 +4172,9 @@ now for those OS that require the first call to os_getloadavg() to be done as root. There will be further calls later for each message received. */ #ifdef LOAD_AVG_NEEDS_ROOT -if (receiving_message && - (queue_only_load >= 0 || - (f.is_inetd && smtp_load_reserve >= 0) - )) - { +if ( receiving_message + && (queue_only_load >= 0 || (f.is_inetd && smtp_load_reserve >= 0))) load_average = OS_GETLOADAVG(); - } #endif /* The queue_only configuration option can be overridden by -odx on the command diff --git a/src/src/functions.h b/src/src/functions.h index 8905d02a2..3b3a12b18 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -878,20 +878,33 @@ return string_sprintf("%s/%s/%s/%s", # endif static inline uschar * -spool_sname(const uschar * purpose, uschar * subdir) +spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir) { return string_sprintf("%s%s%s%s%s", - queue_name, *queue_name ? "/" : "", + q, *q ? "/" : "", purpose, *subdir ? "/" : "", subdir); } static inline uschar * +spool_sname(const uschar * purpose, uschar * subdir) +{ +return spool_q_sname(purpose, queue_name, subdir); +} + +static inline uschar * +spool_q_fname(const uschar * purpose, const uschar * q, + const uschar * subdir, const uschar * fname, const uschar * suffix) +{ +return string_sprintf("%s/%s/%s/%s/%s%s", + spool_directory, q, purpose, subdir, fname, suffix); +} + +static inline uschar * spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname, const uschar * suffix) { -return string_sprintf("%s/%s/%s/%s/%s%s", - spool_directory, queue_name, purpose, subdir, fname, suffix); +return spool_q_fname(purpose, queue_name, subdir, fname, suffix); } static inline void diff --git a/src/src/globals.c b/src/src/globals.c index 677c03e77..07665bf75 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1194,6 +1194,7 @@ uschar *qualify_domain_sender = NULL; uschar *queue_domains = NULL; int queue_interval = -1; uschar *queue_name = US""; +uschar *queue_name_dest = NULL; uschar *queue_only_file = NULL; int queue_only_load = -1; uschar *queue_run_max = US"5"; diff --git a/src/src/globals.h b/src/src/globals.h index e4725a719..0466da500 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -787,6 +787,7 @@ 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 uschar *queue_name_dest; /* Destination queue, for moving messages */ 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/macros.h b/src/src/macros.h index e36c09c47..76913d64e 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -845,7 +845,7 @@ enum { enum { MSG_DELIVER, MSG_FREEZE, MSG_REMOVE, MSG_THAW, MSG_ADD_RECIPIENT, MSG_MARK_ALL_DELIVERED, MSG_MARK_DELIVERED, MSG_EDIT_SENDER, - MSG_SHOW_COPY, MSG_LOAD, + MSG_SHOW_COPY, MSG_LOAD, MSG_SETQUEUE, /* These ones must be last: a test for >= MSG_SHOW_BODY is used to test for actions that list individual spool files. */ MSG_SHOW_BODY, MSG_SHOW_HEADER, MSG_SHOW_LOG }; diff --git a/src/src/queue.c b/src/src/queue.c index 670f51c45..d9ff13375 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -1265,6 +1265,14 @@ switch(action) } + case MSG_SETQUEUE: + /* The global "queue_name_dest" is used as destination, "queue_name" + as source */ + + spool_move_message(id, message_subdir, US"", US""); + break; + + case MSG_MARK_ALL_DELIVERED: for (int i = 0; i < recipients_count; i++) tree_add_nonrecipient(recipients_list[i].address); diff --git a/src/src/spool_out.c b/src/src/spool_out.c index acc6c7b5f..463961f57 100644 --- a/src/src/spool_out.c +++ b/src/src/spool_out.c @@ -417,6 +417,7 @@ start-up time. Arguments: dir base directory name + dq destiinationqueue name subdir subdirectory name id message id suffix suffix to add to id @@ -429,11 +430,11 @@ Returns: TRUE if all went well */ static BOOL -make_link(uschar *dir, uschar *subdir, uschar *id, uschar *suffix, uschar *from, - uschar *to, BOOL noentok) +make_link(uschar *dir, uschar * dq, uschar *subdir, uschar *id, uschar *suffix, + uschar *from, uschar *to, BOOL noentok) { uschar * fname = spool_fname(string_sprintf("%s%s", from, dir), subdir, id, suffix); -uschar * tname = spool_fname(string_sprintf("%s%s", to, dir), subdir, id, suffix); +uschar * tname = spool_q_fname(string_sprintf("%s%s", to, dir), dq, subdir, id, suffix); if (Ulink(fname, tname) < 0 && (!noentok || errno != ENOENT)) { log_write(0, LOG_MAIN|LOG_PANIC, "link(\"%s\", \"%s\") failed while moving " @@ -503,13 +504,15 @@ Returns: TRUE if all is well BOOL spool_move_message(uschar *id, uschar *subdir, uschar *from, uschar *to) { +uschar * dest_qname = queue_name_dest ? queue_name_dest : queue_name; + /* Create any output directories that do not exist. */ (void) directory_make(spool_directory, - spool_sname(string_sprintf("%sinput", to), subdir), + spool_q_sname(string_sprintf("%sinput", to), dest_qname, subdir), INPUT_DIRECTORY_MODE, TRUE); (void) directory_make(spool_directory, - spool_sname(string_sprintf("%smsglog", to), subdir), + spool_q_sname(string_sprintf("%smsglog", to), dest_qname, subdir), INPUT_DIRECTORY_MODE, TRUE); /* Move the message by first creating new hard links for all the files, and @@ -521,9 +524,9 @@ rule of waiting for a -H file before doing anything. When moving messages off the mail spool, the -D file should be open and locked at the time, thus keeping Exim's hands off. */ -if (!make_link(US"msglog", subdir, id, US"", from, to, TRUE) || - !make_link(US"input", subdir, id, US"-D", from, to, FALSE) || - !make_link(US"input", subdir, id, US"-H", from, to, FALSE)) +if (!make_link(US"msglog", dest_qname, subdir, id, US"", from, to, TRUE) || + !make_link(US"input", dest_qname, subdir, id, US"-D", from, to, FALSE) || + !make_link(US"input", dest_qname, subdir, id, US"-H", from, to, FALSE)) return FALSE; if (!break_link(US"input", subdir, id, US"-H", from, FALSE) || @@ -531,8 +534,11 @@ if (!break_link(US"input", subdir, id, US"-H", from, FALSE) || !break_link(US"msglog", subdir, id, US"", from, TRUE)) return FALSE; -log_write(0, LOG_MAIN, "moved from %sinput, %smsglog to %sinput, %smsglog", - from, from, to, to); +log_write(0, LOG_MAIN, "moved from %s%s%s%sinput, %smsglog to %s%s%s%sinput, %smsglog", + *queue_name?"(":"", *queue_name?queue_name:US"", *queue_name?") ":"", + from, from, + *dest_qname?"(":"", *dest_qname?dest_qname:US"", *dest_qname?") ":"", + to, to); return TRUE; } |