1 /* $Cambridge: exim/src/src/routers/ipliteral.c,v 1.2 2004/11/11 11:40:36 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2004 */
8 /* See the file NOTICE for conditions of use and distribution. */
12 #include "rf_functions.h"
13 #include "ipliteral.h"
16 /* Options specific to the ipliteral router. Because some compilers do not like
17 empty declarations ("undefined" in the Standard) we put in a dummy value. */
19 optionlist ipliteral_router_options[] = {
20 { "", opt_hidden, NULL }
23 /* Size of the options list. An extern variable has to be used so that its
24 address can appear in the tables drtables.c. */
26 int ipliteral_router_options_count =
27 sizeof(ipliteral_router_options)/sizeof(optionlist);
29 /* Default private options block for the ipliteral router. Again, a dummy
30 value is present to keep some compilers happy. */
32 ipliteral_router_options_block ipliteral_router_option_defaults = { 0 };
36 /*************************************************
37 * Initialization entry point *
38 *************************************************/
40 /* Called for each instance, after its options have been read, to enable
41 consistency checks to be done, or anything else that needs to be set up. */
44 ipliteral_router_init(router_instance *rblock)
47 ipliteral_router_options_block *ob =
48 (ipliteral_router_options_block *)(rblock->options_block);
55 /*************************************************
57 *************************************************/
59 /* See local README for interface details. This router returns:
62 . the domain is not in the form of an IP literal
65 . verifying the errors address caused a deferment or a big disaster such
66 as an expansion failure (rf_get_errors_address)
67 . expanding a headers_{add,remove} string caused a deferment or another
68 expansion error (rf_get_munge_headers)
69 . a problem in rf_get_transport: no transport when one is needed;
70 failed to expand dynamic transport; failed to find dynamic transport
71 . failure to expand or find a uid/gid (rf_get_ugid via rf_queue_add)
72 . self = "freeze", self = "defer"
84 added address to addr_local or addr_remote, as appropriate for the
85 type of transport; this includes the self="send" case.
89 ipliteral_router_entry(
90 router_instance *rblock, /* data for this instantiation */
91 address_item *addr, /* address we are working on */
92 struct passwd *pw, /* passwd entry after check_local_user */
93 BOOL verify, /* TRUE when verifying */
94 address_item **addr_local, /* add it to this if it's local */
95 address_item **addr_remote, /* add it to this if it's remote */
96 address_item **addr_new, /* put new addresses on here */
97 address_item **addr_succeed) /* put old address here on success */
100 ipliteral_router_options_block *ob =
101 (ipliteral_router_options_block *)(rblock->options_block);
104 uschar *domain = addr->domain;
105 int len = Ustrlen(domain);
108 addr_new = addr_new; /* Keep picky compilers happy */
109 addr_succeed = addr_succeed;
111 DEBUG(D_route) debug_printf("%s router called for %s: domain = %s\n",
112 rblock->name, addr->address, addr->domain);
114 /* Check that the domain is an IP address enclosed in square brackets. If
115 not, the router declines. Otherwise route to the single IP address, setting the
116 host name to "(unnamed)". */
118 if (domain[0] != '[' || domain[len-1] != ']') return DECLINE;
119 domain[len-1] = 0; /* temporarily */
121 if (!string_is_ip_address(domain+1, NULL))
127 /* It seems unlikely that ignore_target_hosts will be used with this router,
128 but if it is set, it should probably work. */
130 if (verify_check_this_host(&(rblock->ignore_target_hosts), NULL, domain,
131 domain + 1, NULL) == OK)
134 debug_printf("%s is in ignore_target_hosts\n", domain+1);
135 addr->message = US"IP literal host explicitly ignored";
140 /* Set up a host item */
142 h = store_get(sizeof(host_item));
145 h->address = string_copy(domain+1);
147 domain[len-1] = ']'; /* restore */
148 h->name = string_copy(domain);
150 h->status = hstatus_unknown;
151 h->why = hwhy_unknown;
154 /* Determine whether the host is the local host, and if so, take action
155 according to the configuration. */
157 if (host_scan_for_local_hosts(h, &h, NULL) == HOST_FOUND_LOCAL)
159 int rc = rf_self_action(addr, h, rblock->self_code, rblock->self_rewrite,
160 rblock->self, addr_new);
161 if (rc != OK) return rc;
164 /* Address is routed to this host */
168 /* Set up the errors address, if any. */
170 rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
171 if (rc != OK) return rc;
173 /* Set up the additional and removeable headers for this address. */
175 rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
176 &(addr->p.remove_headers));
177 if (rc != OK) return rc;
179 /* Fill in the transport, queue the address for local or remote delivery, and
180 yield success. For local delivery, of course, the IP address won't be used. If
181 just verifying, there need not be a transport, in which case it doesn't matter
182 which queue we put the address on. This is all now handled by the route_queue()
185 if (!rf_get_transport(rblock->transport_name, &(rblock->transport),
186 addr, rblock->name, NULL))
189 addr->transport = rblock->transport;
191 return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)?
195 /* End of routers/ipliteral.c */