summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2007-03-13 15:32:47 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2007-03-13 15:32:47 +0000
commitc456d9bb38922c3e5ff511b934a1b7a282935f75 (patch)
tree1f9484eb4987a420ed0e8ca32df38faaab467ea0 /src
parent79749a79c6e24778bcd27236a2846f39ccf18b2a (diff)
Add host_find_failed=ignore and host_all_ignored to manualroute.
Diffstat (limited to 'src')
-rw-r--r--src/src/macros.h5
-rw-r--r--src/src/routers/manualroute.c79
-rw-r--r--src/src/routers/manualroute.h4
-rw-r--r--src/src/routers/rf_lookup_hostlist.c9
4 files changed, 80 insertions, 17 deletions
diff --git a/src/src/macros.h b/src/src/macros.h
index 00e040b5f..f6aca465c 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/macros.h,v 1.32 2007/02/06 11:11:40 ph10 Exp $ */
+/* $Cambridge: exim/src/src/macros.h,v 1.33 2007/03/13 15:32:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -754,13 +754,14 @@ enum {
#define topt_no_body 0x040 /* Omit body */
#define topt_escape_headers 0x080 /* Apply escape check to headers */
-/* Codes for the host_find_failed option. */
+/* Codes for the host_find_failed and host_all_ignored options. */
#define hff_freeze 0
#define hff_defer 1
#define hff_pass 2
#define hff_decline 3
#define hff_fail 4
+#define hff_ignore 5
/* Router information flags */
diff --git a/src/src/routers/manualroute.c b/src/src/routers/manualroute.c
index a6bbcd499..ab304a95f 100644
--- a/src/src/routers/manualroute.c
+++ b/src/src/routers/manualroute.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/manualroute.c,v 1.5 2007/01/08 10:50:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/manualroute.c,v 1.6 2007/03/13 15:32:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -16,6 +16,8 @@
/* Options specific to the manualroute router. */
optionlist manualroute_router_options[] = {
+ { "host_all_ignored", opt_stringptr,
+ (void *)(offsetof(manualroute_router_options_block, host_all_ignored)) },
{ "host_find_failed", opt_stringptr,
(void *)(offsetof(manualroute_router_options_block, host_find_failed)) },
{ "hosts_randomize", opt_bool,
@@ -37,14 +39,30 @@ int manualroute_router_options_count =
/* Default private options block for the manualroute router. */
manualroute_router_options_block manualroute_router_option_defaults = {
- hff_freeze, /* host_find_failed code */
+ -1, /* host_all_ignored code (unset) */
+ -1, /* host_find_failed code (unset) */
FALSE, /* hosts_randomize */
+ US"defer", /* host_all_ignored */
US"freeze", /* host_find_failed */
NULL, /* route_data */
NULL /* route_list */
};
+/* Names and values for host_find_failed and host_all_ignored. */
+
+static uschar *hff_names[] = {
+ US"ignore", /* MUST be first - not valid for host_all_ignored */
+ US"decline",
+ US"defer",
+ US"fail",
+ US"freeze",
+ US"pass" };
+
+static int hff_codes[] = { hff_ignore, hff_decline, hff_defer, hff_fail,
+ hff_freeze, hff_pass };
+
+static int hff_count= sizeof(hff_codes)/sizeof(int);
@@ -60,23 +78,34 @@ manualroute_router_init(router_instance *rblock)
{
manualroute_router_options_block *ob =
(manualroute_router_options_block *)(rblock->options_block);
+int i;
/* Host_find_failed must be a recognized word */
-if (Ustrcmp(ob->host_find_failed, "freeze") == 0)
- ob->hff_code = hff_freeze;
-else if (Ustrcmp(ob->host_find_failed, "decline") == 0)
- ob->hff_code = hff_decline;
-else if (Ustrcmp(ob->host_find_failed, "defer") == 0)
- ob->hff_code = hff_defer;
-else if (Ustrcmp(ob->host_find_failed, "pass") == 0)
- ob->hff_code = hff_pass;
-else if (Ustrcmp(ob->host_find_failed, "fail") == 0)
- ob->hff_code = hff_fail;
-else
+for (i = 0; i < hff_count; i++)
+ {
+ if (Ustrcmp(ob->host_find_failed, hff_names[i]) == 0)
+ {
+ ob->hff_code = hff_codes[i];
+ break;
+ }
+ }
+if (ob->hff_code < 0)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
"unrecognized setting for host_find_failed option", rblock->name);
+for (i = 1; i < hff_count; i++) /* NB starts at 1 to skip "ignore" */
+ {
+ if (Ustrcmp(ob->host_all_ignored, hff_names[i]) == 0)
+ {
+ ob->hai_code = hff_codes[i];
+ break;
+ }
+ }
+if (ob->hai_code < 0)
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
+ "unrecognized setting for host_all_ignored option", rblock->name);
+
/* One of route_list or route_data must be specified */
if ((ob->route_list == NULL && ob->route_data == NULL) ||
@@ -401,6 +430,30 @@ rc = rf_lookup_hostlist(rblock, addr, rblock->ignore_target_hosts, lookup_type,
ob->hff_code, addr_new);
if (rc != OK) return rc;
+/* If host_find_failed is set to "ignore", it is possible for all the hosts to
+be ignored, in which case we will end up with an empty host list. What happens
+is controlled by host_all_ignored. */
+
+if (addr->host_list == NULL)
+ {
+ int i;
+ DEBUG(D_route) debug_printf("host_find_failed ignored every host\n");
+ if (ob->hai_code == hff_decline) return DECLINE;
+ if (ob->hai_code == hff_pass) return PASS;
+
+ for (i = 0; i < hff_count; i++)
+ if (ob->hai_code == hff_codes[i]) break;
+
+ addr->message = string_sprintf("lookup failed for all hosts in %s router: "
+ "host_find_failed=ignore host_all_ignored=%s", rblock->name, hff_names[i]);
+
+ if (ob->hai_code == hff_defer) return DEFER;
+ if (ob->hai_code == hff_fail) return FAIL;
+
+ addr->special_action = SPECIAL_FREEZE;
+ return DEFER;
+ }
+
/* Finally, since we have done all the routing here, there must be a transport
defined for these hosts. It will be a remote one, as a local transport is
dealt with above. However, we don't need one if verifying only. */
diff --git a/src/src/routers/manualroute.h b/src/src/routers/manualroute.h
index 6249d3f6c..38413999b 100644
--- a/src/src/routers/manualroute.h
+++ b/src/src/routers/manualroute.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/manualroute.h,v 1.5 2007/01/08 10:50:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/manualroute.h,v 1.6 2007/03/13 15:32:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -12,8 +12,10 @@
/* Structure for the private options. */
typedef struct {
+ int hai_code;
int hff_code;
BOOL hosts_randomize;
+ uschar *host_all_ignored;
uschar *host_find_failed;
uschar *route_data;
uschar *route_list;
diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c
index 74b59173c..a5beb49f4 100644
--- a/src/src/routers/rf_lookup_hostlist.c
+++ b/src/src/routers/rf_lookup_hostlist.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/rf_lookup_hostlist.c,v 1.8 2007/01/08 10:50:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/rf_lookup_hostlist.c,v 1.9 2007/03/13 15:32:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -157,6 +157,13 @@ for (h = addr->host_list; h != NULL; prev = h, h = next_h)
if (rc == HOST_FIND_FAILED)
{
+ if (hff_code == hff_ignore)
+ {
+ if (prev == NULL) addr->host_list = next_h; else prev->next = next_h;
+ h = prev; /* Because the loop sets prev to h */
+ continue; /* With the next host */
+ }
+
if (hff_code == hff_pass) return PASS;
if (hff_code == hff_decline) return DECLINE;