Merge branch 'SMTPUTF8_1516'. Bug 1516
[exim.git] / src / src / routers / rf_queue_add.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 #include "../exim.h"
9 #include "rf_functions.h"
10
11
12 /*************************************************
13 *        Queue address for transport             *
14 *************************************************/
15
16 /* This function is called to put an address onto the local or remote transport
17 queue, as appropriate. When the driver is for verifying only, a transport need
18 not be set, in which case it doesn't actually matter which queue the address
19 gets put on.
20
21 The generic uid/gid options are inspected and put into the address if they are
22 set. For a remote transport, if there are fallback hosts, they are added to the
23 address.
24
25 Arguments:
26   addr          the address, with the transport field set (if not verify only)
27   paddr_local   pointer to the anchor of the local transport chain
28   paddr_remote  pointer to the anchor of the remote transport chain
29   rblock        the router block
30   pw            password entry if check_local_user was set, or NULL
31
32 Returns:        FALSE on error; the only case is failing to get a uid/gid
33 */
34
35 BOOL
36 rf_queue_add(address_item *addr, address_item **paddr_local,
37   address_item **paddr_remote, router_instance *rblock, struct passwd *pw)
38 {
39 addr->prop.domain_data = deliver_domain_data;         /* Save these values for */
40 addr->prop.localpart_data = deliver_localpart_data;   /* use in the transport */
41
42 /* Handle a local transport */
43
44 if (addr->transport != NULL && addr->transport->info->local)
45   {
46   ugid_block ugid;
47
48   /* Default uid/gid and transport-time home directory are from the passwd file
49   when check_local_user is set, but can be overridden by explicit settings.
50   When getting the home directory out of the password information, set the
51   flag that prevents expansion later. */
52
53   if (pw != NULL)
54     {
55     addr->uid = pw->pw_uid;
56     addr->gid = pw->pw_gid;
57     setflag(addr, af_uid_set|af_gid_set|af_home_expanded);
58     addr->home_dir = string_copy(US pw->pw_dir);
59     }
60
61   if (!rf_get_ugid(rblock, addr, &ugid)) return FALSE;
62   rf_set_ugid(addr, &ugid);
63
64   /* transport_home_directory (in rblock->home_directory) takes priority;
65   otherwise use the expanded value of router_home_directory. The flag also
66   tells the transport not to re-expand it. */
67
68   if (rblock->home_directory != NULL)
69     {
70     addr->home_dir = rblock->home_directory;
71     clearflag(addr, af_home_expanded);
72     }
73   else if (addr->home_dir == NULL && testflag(addr, af_home_expanded))
74     addr->home_dir = deliver_home;
75
76   addr->current_dir = rblock->current_directory;
77
78   addr->next = *paddr_local;
79   *paddr_local = addr;
80   }
81
82 /* For a remote transport, set up the fallback host list, and keep a count of
83 the total number of addresses routed to remote transports. */
84
85 else
86   {
87   addr->fallback_hosts = rblock->fallback_hostlist;
88   addr->next = *paddr_remote;
89   *paddr_remote = addr;
90   remote_delivery_count++;
91   }
92
93 DEBUG(D_route)
94   {
95   debug_printf("queued for %s transport: local_part = %s\ndomain = %s\n"
96     "  errors_to=%s\n",
97     (addr->transport == NULL)? US"<unset>" : addr->transport->name,
98     addr->local_part, addr->domain, addr->prop.errors_address);
99   debug_printf("  domain_data=%s localpart_data=%s\n", addr->prop.domain_data,
100     addr->prop.localpart_data);
101   }
102
103 return TRUE;
104 }
105
106 /* End of rf_queue_add.c */