X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/064a94c915ab9d962a876049ed864a56dc2c7af4..805e5aabc6e28e536153862bcef7268f84108fd7:/src/src/deliver.c diff --git a/src/src/deliver.c b/src/src/deliver.c index e1e3714cc..a80d97842 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/deliver.c,v 1.28 2006/02/08 16:10:46 ph10 Exp $ */ +/* $Cambridge: exim/src/src/deliver.c,v 1.31 2006/04/20 14:11:29 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -228,11 +228,18 @@ if (addr->next == NULL) } /* For multiple addresses, don't set local part, and leave the domain and -self_hostname set only if it is the same for all of them. */ +self_hostname set only if it is the same for all of them. It is possible to +have multiple pipe and file addresses, but only when all addresses have routed +to the same pipe or file. */ else { address_item *addr2; + if (testflag(addr, af_pfr)) + { + if (testflag(addr, af_file)) address_file = addr->local_part; + else if (addr->local_part[0] == '|') address_pipe = addr->local_part; + } for (addr2 = addr->next; addr2 != NULL; addr2 = addr2->next) { if (deliver_domain != NULL && @@ -1743,7 +1750,7 @@ if ((pid = fork()) == 0) if (addr->transport->setup != NULL) { - switch((addr->transport->setup)(addr->transport, addr, NULL, + switch((addr->transport->setup)(addr->transport, addr, NULL, uid, gid, &(addr->message))) { case DEFER: @@ -2119,15 +2126,17 @@ while (addr_local != NULL) disable_logging = tp->disable_logging; - /* Check for batched addresses and possible amalgamation. File deliveries can - never be batched. Skip all the work if either batch_max <= 1 or there aren't - any other addresses for local delivery. */ + /* Check for batched addresses and possible amalgamation. Skip all the work + if either batch_max <= 1 or there aren't any other addresses for local + delivery. */ - if (!testflag(addr, af_file) && tp->batch_max > 1 && addr_local != NULL) + if (tp->batch_max > 1 && addr_local != NULL) { int batch_count = 1; BOOL uses_dom = readconf_depends((driver_instance *)tp, US"domain"); - BOOL uses_lp = readconf_depends((driver_instance *)tp, US"local_part"); + BOOL uses_lp = (testflag(addr, af_pfr) && + (testflag(addr, af_file) || addr->local_part[0] == '|')) || + readconf_depends((driver_instance *)tp, US"local_part"); uschar *batch_id = NULL; address_item **anchor = &addr_local; address_item *last = addr; @@ -2156,6 +2165,7 @@ while (addr_local != NULL) same transport not previously delivered (see comment about 50 lines above) same local part if the transport's configuration contains $local_part + or if this is a file or pipe delivery from a redirection same domain if the transport's configuration contains $domain same errors address same additional headers @@ -2169,6 +2179,7 @@ while (addr_local != NULL) BOOL ok = tp == next->transport && !previously_transported(next, TRUE) && + (addr->flags & (af_pfr|af_file)) == (next->flags & (af_pfr|af_file)) && (!uses_lp || Ustrcmp(next->local_part, addr->local_part) == 0) && (!uses_dom || Ustrcmp(next->domain, addr->domain) == 0) && same_strings(next->p.errors_address, addr->p.errors_address) && @@ -3617,12 +3628,25 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) else return_path = new_return_path; } + /* Find the uid, gid, and use_initgroups setting for this transport. Failure + logs and sets up error messages, so we just post-process and continue with + the next address. */ + + if (!findugid(addr, tp, &uid, &gid, &use_initgroups)) + { + remote_post_process(addr, LOG_MAIN|LOG_PANIC, NULL, fallback); + continue; + } + /* If this transport has a setup function, call it now so that it gets run in this process and not in any subprocess. That way, the results of - any setup that are retained by the transport can be reusable. */ + any setup that are retained by the transport can be reusable. One of the + things the setup does is to set the fallback host lists in the addresses. + That is why it is called at this point, before the continue delivery + processing, because that might use the fallback hosts. */ if (tp->setup != NULL) - (void)((tp->setup)(addr->transport, addr, NULL, NULL)); + (void)((tp->setup)(addr->transport, addr, NULL, uid, gid, NULL)); /* If this is a run to continue delivery down an already-established channel, check that this set of addresses matches the transport and @@ -3698,16 +3722,6 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) transport_filter_argv = NULL; - /* Find the uid, gid, and use_initgroups setting for this transport. Failure - logs and sets up error messages, so we just post-process and continue with - the next address. */ - - if (!findugid(addr, tp, &uid, &gid, &use_initgroups)) - { - remote_post_process(addr, LOG_MAIN|LOG_PANIC, NULL, fallback); - continue; - } - /* Create the pipe for inter-process communication. If pipe creation fails, it is probably because the value of remote_max_parallel is so large that too many file descriptors for pipes have been created. Arrange @@ -4296,15 +4310,15 @@ introducing newlines. All lines are indented by 4; the initial printing position must be set before calling. This function used always to print the error. Nowadays we want to restrict it -to cases such as SMTP errors from a remote host, and errors from :fail: and -filter "fail". We no longer pass other information willy-nilly in bounce and -warning messages. Text in user_message is always output; text in message only -if the af_pass_message flag is set. +to cases such as LMTP/SMTP errors from a remote host, and errors from :fail: +and filter "fail". We no longer pass other information willy-nilly in bounce +and warning messages. Text in user_message is always output; text in message +only if the af_pass_message flag is set. Arguments: addr the address f the FILE to print on - s some leading text + t some leading text Returns: nothing */ @@ -4313,14 +4327,11 @@ static void print_address_error(address_item *addr, FILE *f, uschar *t) { int count = Ustrlen(t); -uschar *s = (addr->user_message != NULL)? addr->user_message : addr->message; +uschar *s = testflag(addr, af_pass_message)? addr->message : NULL; -if (addr->user_message != NULL) - s = addr->user_message; -else +if (s == NULL) { - if (!testflag(addr, af_pass_message) || addr->message == NULL) return; - s = addr->message; + if (addr->user_message != NULL) s = addr->user_message; else return; } fprintf(f, "\n %s", t);