Add option to control use of shutdown by ${readsocket }. Bug 400
[users/heiko/exim.git] / src / src / routers / rf_self_action.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2009 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8
9 #include "../exim.h"
10 #include "rf_functions.h"
11
12
13
14 /*************************************************
15 *        Decode actions for self reference       *
16 *************************************************/
17
18 /* This function is called from a number of routers on receiving
19 HOST_FOUND_LOCAL when looking up a supposedly remote host. The action is
20 controlled by a generic configuration option called "self" on each router,
21 which can be one of:
22
23    . freeze:                       Log the incident, freeze, and return DEFER
24
25    . defer:                        Log the incident and return DEFER
26
27    . fail:                         Fail the address
28
29    . send:                         Carry on with the delivery regardless -
30                                    this makes sense only if the SMTP
31                                    listener on this machine is a differently
32                                    configured MTA
33
34    . pass:                         The router passes; the address
35                                    gets passed to the next router, overriding
36                                    the setting of no_more
37
38    . reroute:<new-domain>          Change the domain to the given domain
39                                    and return REROUTE so it gets passed back
40                                    to the routers.
41
42    . reroute:rewrite:<new-domain>  The same, but headers containing the
43                                    old domain get rewritten.
44
45 These string values are interpreted earlier on, and passed into this function
46 as the values of "code" and "rewrite".
47
48 Arguments:
49   addr       the address being routed
50   host       the host that is local, with MX set (or -1 if MX not used)
51   code       the action to be taken (one of the self_xxx enums)
52   rewrite    TRUE if rewriting headers required for REROUTED
53   new        new domain to be used for REROUTED
54   addr_new   child chain for REROUTEED
55
56 Returns:   DEFER, REROUTED, PASS, FAIL, or OK, according to the value of code.
57 */
58
59 int
60 rf_self_action(address_item *addr, host_item *host, int code, BOOL rewrite,
61   uschar *new, address_item **addr_new)
62 {
63 uschar *msg = (host->mx >= 0)?
64   US"lowest numbered MX record points to local host" :
65   US"remote host address is the local host";
66
67 switch (code)
68   {
69   case self_freeze:
70
71   /* If there is no message id, this is happening during an address
72   verification, so give information about the address that is being verified,
73   and where it has come from. Otherwise, during message delivery, the normal
74   logging for the address will be sufficient. */
75
76   if (message_id[0] == 0)
77     {
78     if (sender_fullhost == NULL)
79       {
80       log_write(0, LOG_MAIN, "%s: %s (while routing <%s>)", msg,
81         addr->domain, addr->address);
82       }
83     else
84       {
85       log_write(0, LOG_MAIN, "%s: %s (while verifying <%s> from host %s)",
86         msg, addr->domain, addr->address, sender_fullhost);
87       }
88     }
89   else
90     log_write(0, LOG_MAIN, "%s: %s", msg, addr->domain);
91
92   addr->message = msg;
93   addr->special_action = SPECIAL_FREEZE;
94   return DEFER;
95
96   case self_defer:
97   addr->message = msg;
98   return DEFER;
99
100   case self_reroute:
101   DEBUG(D_route)
102     {
103     debug_printf("%s: %s", msg, addr->domain);
104     debug_printf(": domain changed to %s\n", new);
105     }
106   rf_change_domain(addr, new, rewrite, addr_new);
107   return REROUTED;
108
109   case self_send:
110   DEBUG(D_route)
111     {
112     debug_printf("%s: %s", msg, addr->domain);
113     debug_printf(": configured to try delivery anyway\n");
114     }
115   return OK;
116
117   case self_pass:    /* This is soft failure; pass to next router */
118   DEBUG(D_route)
119     {
120     debug_printf("%s: %s", msg, addr->domain);
121     debug_printf(": passed to next router (self = pass)\n");
122     }
123   addr->message = msg;
124   addr->self_hostname = string_copy(host->name);
125   return PASS;
126
127   case self_fail:
128   DEBUG(D_route)
129     {
130     debug_printf("%s: %s", msg, addr->domain);
131     debug_printf(": address failed (self = fail)\n");
132     }
133   addr->message = msg;
134   setflag(addr, af_pass_message);
135   return FAIL;
136   }
137
138 return DEFER;   /* paranoia */
139 }
140
141 /* End of rf_self_action.c */