4c6b28867e713a1e8f3898f730afcd66a47e97dc
[exim.git] / src / src / routers / rf_change_domain.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2015 */
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 *          Change domain in an address           *
16 *************************************************/
17
18 /* When a router wants to change the address that is being routed, it is like a
19 redirection. We insert a new parent of the current address to hold the original
20 information, and change the data in the original address, which is now the
21 child. The child address is put onto the addr_new chain. Pick up the local part
22 from the "address" field so as to get it in external form - caseful, and with
23 any quoting retained.
24
25 Arguments:
26   addr        the address block
27   domain      the new domain
28   rewrite     TRUE if headers lines are to be rewritten
29   addr_new    the new address chain
30
31 Returns:      nothing
32 */
33
34 void
35 rf_change_domain(address_item *addr, const uschar *domain, BOOL rewrite,
36   address_item **addr_new)
37 {
38 address_item *parent = store_get(sizeof(address_item));
39 uschar *at = Ustrrchr(addr->address, '@');
40 uschar *address = string_sprintf("%.*s@%s",
41   (int)(at - addr->address), addr->address, domain);
42
43 DEBUG(D_route) debug_printf("domain changed to %s\n", domain);
44
45 /* The current address item is made into the parent, and a new address is set
46 up in the old space. */
47
48 *parent = *addr;
49
50 /* First copy in initializing values, to wipe out stuff such as the named
51 domain cache. Then copy over the propagating fields from the parent. Then set
52 up the new fields. */
53
54 *addr = address_defaults;
55 addr->prop = parent->prop;
56
57 addr->address = address;
58 addr->unique = string_copy(address);
59 addr->parent = parent;
60 parent->child_count = 1;
61
62 addr->next = *addr_new;
63 *addr_new = addr;
64
65 /* Rewrite header lines if requested */
66
67 if (rewrite)
68   {
69   header_line *h;
70   DEBUG(D_route|D_rewrite) debug_printf("rewriting header lines\n");
71   for (h = header_list; h != NULL; h = h->next)
72     {
73     header_line *newh =
74       rewrite_header(h, parent->domain, domain,
75         global_rewrite_rules, rewrite_existflags, TRUE);
76     if (newh != NULL)
77       {
78       h = newh;
79       header_rewritten = TRUE;
80       }
81     }
82   }
83 }
84
85 /* End of rf_change_domain.c */