08d18709aeb09eb9c1947cab846e2852f92ce4b6
[users/jgh/exim.git] / src / src / routers / rf_get_errors_address.c
1 /* $Cambridge: exim/src/src/routers/rf_get_errors_address.c,v 1.3 2005/01/04 10:00:44 ph10 Exp $ */
2
3 /*************************************************
4 *     Exim - an Internet mail transport agent    *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2005 */
8 /* See the file NOTICE for conditions of use and distribution. */
9
10 #include "../exim.h"
11 #include "rf_functions.h"
12
13
14 /*************************************************
15 *        Get errors address for a router         *
16 *************************************************/
17
18 /* This function is called by routers to sort out the errors address for a
19 particular address. If there is a setting in the router block, then expand and
20 verify it, and if it works, use it. Otherwise use any setting that is in the
21 address itself. This might be NULL, meaning unset (the message's sender is then
22 used). Verification isn't done when the original address is just being
23 verified, as otherwise there might be routing loops if someone sets up a silly
24 configuration.
25
26 Arguments:
27   addr         the input address
28   rblock       the router instance
29   verify       TRUE when verifying
30   errors_to    point the errors address here
31
32 Returns:       OK if no problem
33                DEFER if verifying the address caused a deferment
34                  or a big disaster (e.g. expansion failure)
35 */
36
37 int
38 rf_get_errors_address(address_item *addr, router_instance *rblock,
39   BOOL verify, uschar **errors_to)
40 {
41 uschar *s;
42
43 *errors_to = addr->p.errors_address;
44 if (rblock->errors_to == NULL) return OK;
45
46 s = expand_string(rblock->errors_to);
47
48 if (s == NULL)
49   {
50   if (expand_string_forcedfail)
51     {
52     DEBUG(D_route)
53       debug_printf("forced expansion failure - ignoring errors_to\n");
54     return OK;
55     }
56   addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
57     rblock->name, rblock->errors_to, expand_string_message);
58   return DEFER;
59   }
60
61 /* If the errors_to address is empty, it means "ignore errors" */
62
63 if (*s == 0)
64   {
65   setflag(addr, af_ignore_error);      /* For locally detected errors */
66   *errors_to = US"";                   /* Return path for SMTP */
67   return OK;
68   }
69
70 /* If we are already verifying, do not check the errors address, in order to
71 save effort (but we do verify when testing an address). When we do verify, set
72 the sender address to null, because that's what it will be when sending an
73 error message, and there are now configuration options that control the running
74 of routers by checking the sender address. When testing an address, there may
75 not be a sender address. We also need to save and restore the expansion values
76 associated with an address. */
77
78 if (verify)
79   {
80   *errors_to = s;
81   DEBUG(D_route)
82     debug_printf("skipped verify errors_to address: already verifying\n");
83   }
84 else
85   {
86   BOOL save_address_test_mode = address_test_mode;
87   int save1 = 0;
88   int i;
89   uschar ***p;
90   uschar *address_expansions_save[ADDRESS_EXPANSIONS_COUNT];
91   address_item *snew = deliver_make_addr(s, FALSE);
92
93   if (sender_address != NULL)
94     {
95     save1 = sender_address[0];
96     sender_address[0] = 0;
97     }
98
99   for (i = 0, p = address_expansions; *p != NULL;)
100     address_expansions_save[i++] = **p++;
101   address_test_mode = FALSE;
102
103   DEBUG(D_route|D_verify)
104     debug_printf("------ Verifying errors address %s ------\n", s);
105   if (verify_address(snew, NULL, vopt_is_recipient | vopt_qualify, -1, -1, -1,
106     NULL, NULL, NULL) == OK) *errors_to = snew->address;
107   DEBUG(D_route|D_verify)
108     debug_printf("------ End verifying errors address %s ------\n", s);
109
110   address_test_mode = save_address_test_mode;
111   for (i = 0, p = address_expansions; *p != NULL;)
112     **p++ = address_expansions_save[i++];
113
114   if (sender_address != NULL) sender_address[0] = save1;
115   }
116
117 return OK;
118 }
119
120 /* End of rf_get_errors_address.c */